mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: dlna
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:PiliPalaX/http/danmaku.dart';
|
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:floating/floating.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
@@ -494,4 +496,102 @@ class VideoDetailController extends GetxController
|
|||||||
}
|
}
|
||||||
return result;
|
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<DlnaPanel> createState() => _DlnaPanelState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DlnaPanelState extends State<DlnaPanel> {
|
||||||
|
final DLNAManager searcher = DLNAManager();
|
||||||
|
late final DeviceManager manager;
|
||||||
|
List<DLNADevice> 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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1440,6 +1440,22 @@ class _HeaderControlState extends State<HeaderControl> {
|
|||||||
// ),
|
// ),
|
||||||
// fuc: () => _.screenshot(),
|
// 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(
|
SizedBox(
|
||||||
width: 42,
|
width: 42,
|
||||||
height: 34,
|
height: 34,
|
||||||
|
|||||||
@@ -447,6 +447,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
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.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.8"
|
||||||
dynamic_color:
|
dynamic_color:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ dependencies:
|
|||||||
extended_text: ^14.0.1
|
extended_text: ^14.0.1
|
||||||
chat_bottom_container: ^0.2.0
|
chat_bottom_container: ^0.2.0
|
||||||
image_picker: ^1.1.2
|
image_picker: ^1.1.2
|
||||||
|
dlna_dart: ^0.0.8
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
mime:
|
mime:
|
||||||
|
|||||||
Reference in New Issue
Block a user