推流
apivideo_live_stream: ^1.1.3
组件地址:https://pub-web.flutter-io.cn/packages/apivideo_live_stream
1.初始化和检查权限
import 'package:apivideo_live_stream/apivideo_live_stream.dart'; //导包 late ApiVideoLiveStreamController _controllerStream; //直播推流 //重要代码 需要绑定key不然切换页面会停止摄像头采集 final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); @override void initState() { initPlatformState(); //检查权限 _controllerStream = createLiveStreamController(); _controllerStream.initialize().catchError((e) {}); //延迟1秒 直播推流 Future.delayed(Duration(milliseconds: 1000), () { startrecording(); //开始推流 }); } // 检查权限 我这里封装了方法,你自己按照自己的来 Future<void> initPlatformState() async { //相机权限 if (await camerabool() == false) { return; } //录音权限 if (await microphonebool() == false) { return; } } //直播推流初始化 ApiVideoLiveStreamController createLiveStreamController() { return ApiVideoLiveStreamController( initialAudioConfig: AudioConfig(), //设置音频属性 initialVideoConfig: VideoConfig.withDefaultBitrate(resolution: Resolution.RESOLUTION_720), //设置视频属性 initialCameraPosition: CameraPosition.front, //设置摄像头是正面还是反面 onConnectionSuccess: () { //连接成功 setState(() {}); }, onConnectionFailed: (error) { //连接失败时 if (mounted) {} }, onDisconnection: () { //断开连接时 if (mounted) {} }, onError: (error) { // 获取错误,如缺少权限, if (mounted) {} }); }
2.开始推流
//开始推流
startrecording() async {
startStreaming(rtmpurl).then((_) {
if (mounted) {}
}).catchError((error) {
print('开始推流失败+'error.toString())
});
}
//开始推流
startStreaming(String rtmpurl) async {
// '?token=' + token
return await _controllerStream.startStreaming(
streamKey: '测试时这里随便', url: 'rtmp://你自己的rtmp地址');
}
3.主播预览自己的画面
//主播 UI
Center(
child: SizedBox.expand(
child: FittedBox(
fit: BoxFit.cover,
clipBehavior: Clip.hardEdge,
child: Container(
width:MediaQuery.of(context).size.width,
child: ApiVideoCameraPreview(key: _scaffoldKey, controller: _controllerStream)))))
拉流
fijkplayer: ^0.11.0
import 'package:fijkplayer/fijkplayer.dart';//导包
FijkPlayer fplayer= FijkPlayer();
// 开始拉流
ligaturePullflow() {
attribute(fplayer); //延迟设置
Fpalyer.setDataSource('播放地址 一般是.flv', autoPlay: true); //播放
}
//延迟设置
attribute(FijkPlayer fijkplayer) {
await fijkplayer.setVolume(0.6); //设置音量
// 解决延迟
fijkplayer.setOption(1, "analyzemaxduration", 100); //设置分析最大持续时间
fijkplayer.setOption(1, "probesize", 1024); //设置探测文件的大小。
fijkplayer.setOption(FijkOption.playerCategory, "reconnect", 5); //设置重新连接次数。
fijkplayer.setOption(1, "flush_packets", 1); // 启用刷新数据包。
fijkplayer.setOption(4, "packet-buffering", 0); //禁用数据包缓冲
fijkplayer.setOption(4, "framedrop", 1); //启用帧丢弃,允许在视频渲染过程中丢弃一些帧,以减少延迟。
}
UI画面
FijkView(
player: fplayer,
fit: FijkFit.cover,
panelBuilder: (FijkPlayer player, FijkData data, BuildContext context, Size viewSize, Rect texturePos) {
return Container();
},
),
销毁
@override
void dispose() async {
_controllerStream.stopStreaming();//停止推流
_controllerStream.dispose(); //释放 推流
fplayer.release(); //释放播放
}
Android和iOS都可以推流和拉流,本人亲测有效,如有补充不全 请谅解