Flutter视频录制与回放插件flutter_kinescope_sdk的使用
Flutter视频录制与回放插件flutter_kinescope_sdk的使用
简介
flutter_kinescope_sdk
是一个用于Flutter应用的Kinescope播放器插件,支持Android和iOS平台。该插件底层依赖于 flutter_inappwebview
实现。
许可证
系统要求
- Android: 需要
minSdkVersion 17
并且需要添加对androidx
的支持(参见 AndroidX Migration) - iOS: 需要
--ios-language swift
和 Xcode版本 >= 11
安装
在你的 pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter_kinescope_sdk: ^0.1.10
使用方法
下面是一个简单的示例,展示了如何在Flutter应用中集成和使用 flutter_kinescope_sdk
插件。
示例代码
import 'package:flutter/material.dart';
import 'package:flutter_kinescope_sdk/flutter_kinescope_sdk.dart';
const _initialVideoId = 'sEsxJQ7Hi4QLWwbmZEFfgz';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Kinescope SDK example',
theme: ThemeData(
primarySwatch: Colors.purple,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final _textEditingController = TextEditingController(text: _initialVideoId);
late KinescopePlayerController _kinescopeController;
@override
void initState() {
super.initState();
_kinescopeController = KinescopePlayerController(
_initialVideoId,
parameters: const PlayerParameters(
watermark: WatermarkParameters(
mode: 'random',
text: 'water-text',
),
),
);
}
@override
Widget build(BuildContext context) {
return StreamBuilder<KinescopePlayerStatus>(
stream: _kinescopeController.status,
initialData: KinescopePlayerStatus.unknown,
builder: (context, snapshot) {
final isUnknown = snapshot.data == KinescopePlayerStatus.unknown;
return Scaffold(
appBar: AppBar(
title: const Text('Kinescope SDK example'),
),
body: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height / 4,
child: KinescopePlayer(
controller: _kinescopeController,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _textEditingController,
decoration: const InputDecoration(labelText: 'Video ID'),
onSubmitted: (id) {
_kinescopeController.load(id);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: !isUnknown ? _play : null,
icon: const Icon(Icons.play_arrow),
),
IconButton(
onPressed: !isUnknown ? _pause : null,
icon: const Icon(Icons.pause),
),
IconButton(
onPressed: !isUnknown ? _stop : null,
icon: const Icon(Icons.stop),
),
IconButton(
onPressed: !isUnknown ? _unmute : null,
icon: const Icon(Icons.volume_up),
),
IconButton(
onPressed: !isUnknown ? _mute : null,
icon: const Icon(Icons.volume_off),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
IconButton(
onPressed: !isUnknown ? _rewindBackward : null,
icon: const Icon(Icons.fast_rewind),
tooltip: 'rewind 10 seconds backward',
),
const Text('- 10 sec'),
],
),
TextButton(
onPressed: !isUnknown ? _seekToCenter : null,
child: const Text('seek to center'),
),
Column(
children: [
IconButton(
onPressed: !isUnknown ? _rewindForward : null,
icon: const RotatedBox(
quarterTurns: 2,
child: Icon(Icons.fast_rewind),
),
tooltip: 'rewind 10 seconds forward',
),
const Text('+ 10 sec'),
],
),
],
),
),
Container(
width: double.infinity,
height: 50,
margin: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(16),
),
child: Center(
child: Text(
'KinescopePlayerStatus: ${snapshot.data}',
style: const TextStyle(color: Colors.white),
),
),
),
],
),
);
},
);
}
void _pause() {
_kinescopeController.pause();
}
void _play() {
_kinescopeController.play();
}
void _stop() {
_kinescopeController.stop();
}
void _unmute() {
_kinescopeController.unmute();
}
void _mute() {
_kinescopeController.mute();
}
Future<void> _rewindBackward() async {
final currentTime = await _kinescopeController.getCurrentTime();
final duration = Duration(
seconds: currentTime.inSeconds - 10 > 0 ? currentTime.inSeconds - 10 : 0,
);
_kinescopeController.seekTo(duration);
}
Future<void> _rewindForward() async {
final currentTime = await _kinescopeController.getCurrentTime();
_kinescopeController.seekTo(
currentTime + const Duration(seconds: 10),
);
}
Future<void> _seekToCenter() async {
final duration = await _kinescopeController.getDuration();
_kinescopeController.seekTo(
Duration(
seconds: duration.inSeconds ~/ 2,
),
);
}
}
可用方法
以下是 KinescopePlayerController
提供的方法列表:
方法 | 描述 |
---|---|
play() | 播放当前加载的视频 |
pause() | 暂停当前播放的视频 |
stop() | 停止并取消当前视频的加载 |
load(String videoId) | 加载并播放指定的视频 |
getCurrentTime() | 返回当前播放位置 |
getDuration() | 返回视频的总时长 |
seekTo(Duration position) | 跳转到视频中的指定时间点 |
mute() | 静音 |
unmute() | 取消静音 |
setVolume(double volume) | 设置音量(仅适用于Android) |
PlayerParameters 参数
你可以通过 PlayerParameters
来设置初始的Kinescope播放器参数:
参数 | 描述 |
---|---|
autoplay | 是否自动播放视频,默认为 false |
muted | 是否静音,默认为 true |
loop | 视频结束后是否自动重新开始播放 |
userAgent | 覆盖默认的UserAgent |
externalId | 代表外部系统的用户ID,用于分析,默认为空字符串 |
autofocus | 设置焦点到播放器,默认为 true |
playsinline | 在不全屏的情况下播放视频 |
preload | 预加载视频元数据,默认为 true |
texttrack | 启用字幕 |
dnt | 禁用发送分析数据 |
background | 禁用任何控件,并将 autoplay , muted , loop 设置为 true |
t | 指定跳转的时间点 |
transparent | 透明背景颜色 |
speedbtn | 显示播放速率按钮 |
header | 显示头部 |
controls | 显示控制按钮 |
disableFiles | 隐藏附加材料 |
watermark | 设置水印 |
更多详细信息可以参考 GitHub上的示例。
更多关于Flutter视频录制与回放插件flutter_kinescope_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter视频录制与回放插件flutter_kinescope_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用flutter_kinescope_sdk
插件进行视频录制与回放的示例代码。请注意,这个示例假设你已经在pubspec.yaml
文件中添加了flutter_kinescope_sdk
依赖,并运行了flutter pub get
。
首先,确保你的pubspec.yaml
文件包含以下依赖:
dependencies:
flutter:
sdk: flutter
flutter_kinescope_sdk: ^latest_version # 替换为实际的最新版本号
接下来,创建一个Flutter项目并添加以下代码。
1. 初始化插件和权限
在android/app/src/main/AndroidManifest.xml
中,添加必要的权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
在ios/Runner/Info.plist
中,添加相机和麦克风权限请求(如果需要iOS支持):
<key>NSCameraUsageDescription</key>
<string>App needs access to the camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>App needs access to the microphone</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>App needs access to the photo library</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App needs access to the photo library</string>
2. 主代码实现
在你的main.dart
文件中,实现视频录制与回放功能:
import 'package:flutter/material.dart';
import 'package:flutter_kinescope_sdk/flutter_kinescope_sdk.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
FlutterKinescope? _kinescope;
String? _videoPath;
@override
void initState() {
super.initState();
_initKinescope();
}
Future<void> _initKinescope() async {
// 请求必要的权限
var status = await Permission.camera.status;
if (!status.isGranted) {
await Permission.camera.request();
}
status = await Permission.microphone.status;
if (!status.isGranted) {
await Permission.microphone.request();
}
status = await Permission.storage.status;
if (!status.isGranted) {
await Permission.storage.request();
}
// 初始化Kinescope
_kinescope = FlutterKinescope();
}
Future<void> _startRecording() async {
if (_kinescope!.isRecording) {
return;
}
String? resultPath = await _kinescope!.startRecord({
'videoQuality': 'HIGH', // 可以选择 'LOW', 'MEDIUM', 'HIGH'
'outputPath': '/storage/emulated/0/DCIM/Camera/', // 指定输出路径,可以是绝对路径或相对路径
});
setState(() {
_videoPath = resultPath;
});
}
Future<void> _stopRecording() async {
if (!_kinescope!.isRecording) {
return;
}
await _kinescope!.stopRecord();
}
Future<void> _playVideo() async {
if (_videoPath == null) {
return;
}
// 使用系统的视频播放器打开录制的视频
await _kinescope!.playVideo(_videoPath!);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Kinescope SDK Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: _startRecording,
child: Text('Start Recording'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _stopRecording,
child: Text('Stop Recording'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: _playVideo,
child: Text('Play Video'),
),
],
),
),
);
}
@override
void dispose() {
_kinescope?.dispose();
super.dispose();
}
}
3. 注意事项
- 确保你已经添加了
permission_handler
依赖来处理权限请求。 - 录制视频时,指定的输出路径需要确保应用有写权限。
- 播放视频时,
_kinescope!.playVideo
方法会使用系统默认的视频播放器打开指定路径的视频文件。
这个示例代码展示了如何使用flutter_kinescope_sdk
插件进行视频录制与回放。实际应用中,你可能需要根据具体需求进行更多的配置和处理。