Flutter视频投屏插件video_cast的使用
Flutter视频投屏插件video_cast的使用
简介
video_cast
是一个用于在Chromecast设备上播放视频的Flutter插件。这是对 flutter_video_cast_v2
插件的修改版本,增加了额外的功能。
安装
首先,在你的 pubspec.yaml
文件中添加 video_cast
作为依赖项。
Android 配置
在你的模块(应用级别)Gradle文件(通常是 android/app/build.gradle
)中添加以下依赖:
implementation 'com.google.android.gms:play-services-cast-framework:21.2.0'
implementation 'com.google.android.exoplayer:extension-cast:2.17.1'
在应用程序清单 android/app/src/main/AndroidManifest.xml
中将 MainActivity
的主题设置为 @style/Theme.AppCompat.NoActionBar
:
<manifest ...
<application ...
<meta-data android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.android.exoplayer2.ext.cast.DefaultCastOptionsProvider"/>
...
<activity android:theme="@style/Theme.AppCompat.NoActionBar" ...
使 MainActivity
继承 FlutterFragmentActivity
并初始化 Cast 上下文:
CastContext.getSharedInstance(applicationContext)
使用 ChromeCastButton
你现在可以在小部件树中添加一个 ChromeCastButton
小部件。
按钮可以通过传递给 ChromeCastButton
的 onButtonCreated
回调中的 ChromeCastController
进行控制。
import 'package:flutter/material.dart';
import 'package:video_cast/video_cast.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: CastSample(),
);
}
}
class CastSample extends StatefulWidget {
[@override](/user/override)
_CastSampleState createState() => _CastSampleState();
}
class _CastSampleState extends State<CastSample> {
ChromeCastController _controller;
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cast Sample'),
actions: [
ChromeCastButton(
onButtonCreated: (controller) {
setState(() => _controller = controller);
_controller?.addSessionListener();
},
onSessionStarted: () {
_controller?.loadMedia(
url:
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
position: 30000, // 开始位置为30秒
autoplay: true,
title: "Spider-Man: No Way Home",
description:
"Peter Parker is unmasked and no longer able to separate his normal life from the high-stakes of being a super-hero. When he asks for help from Doctor Strange the stakes become even more dangerous, forcing him to discover what it truly means to be Spider-Man.",
image:
"https://terrigen-cdn-dev.marvel.com/content/prod/1x/marvsmposterbk_intdesign.jpg",
type: ChromeCastMediaType.movie,
);
},
),
],
),
);
}
}
完整示例代码
import 'package:flutter/material.dart';
import 'package:video_cast/chrome_cast_media_type.dart';
import 'package:video_cast/chrome_cast_subtitle.dart';
import 'package:video_cast/video_cast.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
ChromeCastController? castController;
[@override](/user/override)
void initState() {
super.initState();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Column(
children: [
const Text("ChromeCastButton"),
const SizedBox(
height: 5,
),
ChromeCastButton(
color: Colors.red, // 按钮颜色
onButtonCreated: (controller) {
castController = controller;
castController?.addSessionListener(); // 添加会话监听器
},
onSessionEnding: (position) {
print("in app ending");
print("position is $position");
},
onSessionEnded: () {
print("in app ended");
},
onSessionStarted: () {
print("in app started");
castController?.onProgressEvent().listen((event) {
print("in app progress ${event.inMilliseconds}");
});
castController?.loadMedia(
url:
"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
position: 30000, // 开始位置为30秒
autoplay: true,
title: "Spider-Man: No Way Home",
description:
"Peter Parker is unmasked and no longer able to separate his normal life from the high-stakes of being a super-hero. When he asks for help from Doctor Strange the stakes become even more dangerous, forcing him to discover what it truly means to be Spider-Man.",
image:
"https://terrigen-cdn-dev.marvel.com/content/prod/1x/marvsmposterbk_intdesign.jpg",
type: ChromeCastMediaType.movie,
subtitles: [
ChromeCastSubtitle(
id: 1,
language: "en-US",
name: "English",
source:
"https://cc.2cdns.com/3e/62/3e62d0109500abf55acf229a0599a20d/3e62d0109500abf55acf229a0599a20d.vtt",
),
ChromeCastSubtitle(
id: 2,
language: "ar",
name: "Arabic",
source:
"https://cc.2cdns.com/91/bd/91bdc91ffff0906bd54f0711eb3e786f/91bdc91ffff0906bd54f0711eb3e786f.vtt",
),
],
);
},
),
ElevatedButton(
onPressed: () {
castController?.setTrack(subId: 1); // 设置字幕轨道1
},
child: const Text("Set Track 1"),
),
ElevatedButton(
onPressed: () {
castController?.setTrack(subId: 2); // 设置字幕轨道2
},
child: const Text("Set Track 2"),
),
ElevatedButton(
onPressed: () {
castController?.disableTrack(); // 禁用字幕轨道
},
child: const Text("Disable Track"),
),
],
),
),
),
);
}
[@override](/user/override)
void dispose() {
castController?.cancelTimer(); // 取消计时器
super.dispose();
}
}
更多关于Flutter视频投屏插件video_cast的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter视频投屏插件video_cast的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用video_cast
插件来实现视频投屏的示例代码。video_cast
插件允许你将Flutter应用中的视频内容投屏到支持DLNA或Chromecast的设备上。
首先,你需要在你的pubspec.yaml
文件中添加video_cast
依赖:
dependencies:
flutter:
sdk: flutter
video_cast: ^0.4.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
接下来,在你的Flutter应用中,你可以按照以下步骤来使用video_cast
插件:
- 初始化Cast上下文:
import 'package:flutter/material.dart';
import 'package:video_cast/video_cast.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late CastContext castContext;
@override
void initState() {
super.initState();
// 初始化Cast上下文
castContext = CastContext(
onDevicesUpdated: _devicesUpdated,
onSessionUpdated: _sessionUpdated,
);
castContext.initialize();
}
@override
void dispose() {
castContext.dispose();
super.dispose();
}
void _devicesUpdated(List<CastDevice> devices) {
// 处理设备更新事件
print("Devices updated: $devices");
}
void _sessionUpdated(CastSession? session) {
// 处理会话更新事件
print("Session updated: $session");
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Video Cast Example'),
),
body: Center(
child: CastButton(
castContext: castContext,
videoUrl: 'https://www.example.com/video.mp4', // 你的视频URL
text: 'Cast Video',
),
),
),
);
}
}
- 创建CastButton组件:
由于video_cast
插件没有自带的按钮组件,你可以自定义一个按钮来触发投屏操作。以下是一个简单的CastButton
组件示例:
import 'package:flutter/material.dart';
import 'package:video_cast/video_cast.dart';
class CastButton extends StatelessWidget {
final CastContext castContext;
final String videoUrl;
final String text;
const CastButton({
Key? key,
required this.castContext,
required this.videoUrl,
required this.text,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () async {
List<CastDevice> devices = castContext.devices;
if (devices.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('No cast devices found')),
);
return;
}
CastDevice device = devices.first; // 选择第一个设备,实际应用中你可能需要让用户选择
CastSession session = await castContext.startSession(device, videoUrl);
if (session != null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Casting to ${device.friendlyName}')),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Failed to start casting')),
);
}
},
child: Text(text),
);
}
}
以上代码展示了一个基本的Flutter应用,它使用video_cast
插件来检测可用的投屏设备,并允许用户点击按钮将视频投屏到第一个检测到的设备上。
请注意,实际应用中你可能需要处理更多的边缘情况和用户交互,比如让用户选择特定的投屏设备,处理投屏过程中的错误,以及在投屏结束时进行适当的清理工作。此外,务必确保你的视频URL是有效的,并且目标设备支持DLNA或Chromecast协议。