feat: 简单实现投屏
This commit is contained in:
111
lib/pages/dlna/index.dart
Normal file
111
lib/pages/dlna/index.dart
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:dlna_dart/dlna.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class LiveDlnaPage extends StatefulWidget {
|
||||||
|
final String datasource;
|
||||||
|
|
||||||
|
const LiveDlnaPage({Key? key, required this.datasource}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<LiveDlnaPage> createState() => _LiveDlnaPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LiveDlnaPageState extends State<LiveDlnaPage> {
|
||||||
|
final Map<String, DLNADevice> _deviceList = {};
|
||||||
|
final DLNAManager searcher = DLNAManager();
|
||||||
|
late final Timer stopSearchTimer;
|
||||||
|
String selectDeviceKey = '';
|
||||||
|
bool isSearching = true;
|
||||||
|
|
||||||
|
DLNADevice? get device => _deviceList[selectDeviceKey];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
stopSearchTimer = Timer(const Duration(seconds: 20), () {
|
||||||
|
setState(() => isSearching = false);
|
||||||
|
searcher.stop();
|
||||||
|
});
|
||||||
|
searcher.stop();
|
||||||
|
startSearch();
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
searcher.stop();
|
||||||
|
stopSearchTimer.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void startSearch() async {
|
||||||
|
// clear old devices
|
||||||
|
isSearching = true;
|
||||||
|
selectDeviceKey = '';
|
||||||
|
_deviceList.clear();
|
||||||
|
setState(() {});
|
||||||
|
// start search server
|
||||||
|
final m = await searcher.start();
|
||||||
|
m.devices.stream.listen((deviceList) {
|
||||||
|
deviceList.forEach((key, value) {
|
||||||
|
_deviceList[key] = value;
|
||||||
|
});
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
// close the server, the closed server can be start by call searcher.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectDevice(String key) {
|
||||||
|
if (selectDeviceKey.isNotEmpty) device?.pause();
|
||||||
|
|
||||||
|
selectDeviceKey = key;
|
||||||
|
device?.setUrl(widget.datasource);
|
||||||
|
device?.play();
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
Widget cur;
|
||||||
|
if (isSearching && _deviceList.isEmpty) {
|
||||||
|
cur = const Center(child: CircularProgressIndicator());
|
||||||
|
} else if (_deviceList.isEmpty) {
|
||||||
|
cur = Center(
|
||||||
|
child: Text(
|
||||||
|
'没有找到设备',
|
||||||
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
cur = ListView(
|
||||||
|
children: _deviceList.keys
|
||||||
|
.map<Widget>((key) => ListTile(
|
||||||
|
contentPadding: const EdgeInsets.all(2),
|
||||||
|
title: Text(_deviceList[key]!.info.friendlyName),
|
||||||
|
subtitle: Text(key),
|
||||||
|
onTap: () => selectDevice(key),
|
||||||
|
))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AlertDialog(
|
||||||
|
title: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text('查找设备'),
|
||||||
|
IconButton(
|
||||||
|
onPressed: startSearch,
|
||||||
|
icon: const Icon(Icons.refresh_rounded),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
content: SizedBox(
|
||||||
|
height: 200,
|
||||||
|
width: 200,
|
||||||
|
child: cur,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ import 'package:ns_danmaku/ns_danmaku.dart';
|
|||||||
import 'package:pilipala/http/user.dart';
|
import 'package:pilipala/http/user.dart';
|
||||||
import 'package:pilipala/models/video/play/quality.dart';
|
import 'package:pilipala/models/video/play/quality.dart';
|
||||||
import 'package:pilipala/models/video/play/url.dart';
|
import 'package:pilipala/models/video/play/url.dart';
|
||||||
|
import 'package:pilipala/pages/dlna/index.dart';
|
||||||
import 'package:pilipala/pages/video/detail/index.dart';
|
import 'package:pilipala/pages/video/detail/index.dart';
|
||||||
import 'package:pilipala/pages/video/detail/introduction/widgets/menu_row.dart';
|
import 'package:pilipala/pages/video/detail/introduction/widgets/menu_row.dart';
|
||||||
import 'package:pilipala/plugin/pl_player/index.dart';
|
import 'package:pilipala/plugin/pl_player/index.dart';
|
||||||
@ -1209,6 +1210,22 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
// ),
|
// ),
|
||||||
// fuc: () => _.screenshot(),
|
// fuc: () => _.screenshot(),
|
||||||
// ),
|
// ),
|
||||||
|
ComBtn(
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.cast,
|
||||||
|
size: 19,
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
fuc: () async {
|
||||||
|
showDialog<void>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return LiveDlnaPage(
|
||||||
|
datasource: widget.videoDetailCtr!.videoUrl);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
if (isFullScreen.value) ...[
|
if (isFullScreen.value) ...[
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 56,
|
width: 56,
|
||||||
|
|||||||
@ -409,6 +409,14 @@ packages:
|
|||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
dlna_dart:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dlna_dart
|
||||||
|
sha256: ae07c1c53077bbf58756fa589f936968719b0085441981d33e74f82f89d1d281
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.8"
|
||||||
dynamic_color:
|
dynamic_color:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -144,6 +144,8 @@ dependencies:
|
|||||||
disable_battery_optimization: ^1.1.1
|
disable_battery_optimization: ^1.1.1
|
||||||
# 展开/收起
|
# 展开/收起
|
||||||
expandable: ^5.0.1
|
expandable: ^5.0.1
|
||||||
|
# 投屏
|
||||||
|
dlna_dart: ^0.0.8
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user