From 341092a5ed75ec6b5e041241805e9359b3a390cc Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Sat, 28 Sep 2024 17:59:51 +0800 Subject: [PATCH] feat: dlna --- lib/pages/video/detail/controller.dart | 100 ++++++++++++++++++ .../video/detail/widgets/header_control.dart | 16 +++ pubspec.lock | 8 ++ pubspec.yaml | 1 + 4 files changed, 125 insertions(+) diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index bd508611..dd734406 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'dart:io'; import 'package:PiliPalaX/http/danmaku.dart'; +import 'package:dlna_dart/dlna.dart'; +import 'package:dlna_dart/xmlParser.dart'; import 'package:floating/floating.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; @@ -494,4 +496,102 @@ class VideoDetailController extends GetxController } return result; } + + void cast(BuildContext context) { + if (videoUrl != null && audioUrl != null) { + showDialog( + context: context, + builder: (_) => DlnaPanel( + videoUrl: videoUrl!, + audioUrl: audioUrl!, + ), + ); + } else { + SmartDialog.showToast('wait for init'); + } + } +} + +class DlnaPanel extends StatefulWidget { + const DlnaPanel({super.key, required this.videoUrl, required this.audioUrl}); + + final String videoUrl; + final String audioUrl; + + @override + State createState() => _DlnaPanelState(); +} + +class _DlnaPanelState extends State { + final DLNAManager searcher = DLNAManager(); + late final DeviceManager manager; + List deviceList = []; + + @override + void initState() { + super.initState(); + init(); + } + + init() async { + manager = await searcher.start(); + manager.devices.stream.listen((dlist) { + setState(() { + deviceList = dlist.values.toList(); + }); + }); + } + + @override + void dispose() { + searcher.stop(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('查找设备'), + IconButton( + onPressed: () { + setState(() { + deviceList.clear(); + }); + }, + icon: const Icon(Icons.refresh), + ), + ], + ), + content: Container( + height: 225, + width: context.width, + alignment: deviceList.isEmpty ? Alignment.center : null, + child: deviceList.isEmpty + ? const CircularProgressIndicator() + : ListView.builder( + shrinkWrap: true, + itemBuilder: (_, index) => ListTile( + onTap: () async { + try { + await deviceList[index].setUrl(widget.videoUrl); + await deviceList[index].setUrl( + widget.audioUrl, + type: PlayType.Audio, + ); + await deviceList[index].play(); + } catch (e) { + SmartDialog.showToast(e.toString()); + } + }, + title: Text(deviceList[index].info.friendlyName), + subtitle: Text(deviceList[index].info.URLBase), + ), + itemCount: deviceList.length, + ), + ), + ); + } } diff --git a/lib/pages/video/detail/widgets/header_control.dart b/lib/pages/video/detail/widgets/header_control.dart index c55dac19..c0e978ae 100644 --- a/lib/pages/video/detail/widgets/header_control.dart +++ b/lib/pages/video/detail/widgets/header_control.dart @@ -1440,6 +1440,22 @@ class _HeaderControlState extends State { // ), // fuc: () => _.screenshot(), // ), + SizedBox( + width: 42, + height: 34, + child: IconButton( + tooltip: '投屏', + style: ButtonStyle( + padding: WidgetStateProperty.all(EdgeInsets.zero), + ), + onPressed:()=> widget.videoDetailCtr?.cast(context), + icon: const Icon( + Icons.cast, + size: 19, + color: Colors.white, + ), + ), + ), SizedBox( width: 42, height: 34, diff --git a/pubspec.lock b/pubspec.lock index c3353e6c..08e2c98a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -447,6 +447,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" + dlna_dart: + dependency: "direct main" + description: + name: dlna_dart + sha256: ae07c1c53077bbf58756fa589f936968719b0085441981d33e74f82f89d1d281 + url: "https://pub.dev" + source: hosted + version: "0.0.8" dynamic_color: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 1a020673..7aea7c09 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -160,6 +160,7 @@ dependencies: extended_text: ^14.0.1 chat_bottom_container: ^0.2.0 image_picker: ^1.1.2 + dlna_dart: ^0.0.8 dependency_overrides: mime: