Defensor APP 直播功能开发

Defensor APP 直播功能开发,  在 Flutter 中可以用一个第三方库 fijkplayer 来做. 
GitHub 地址: https://github.com/befovy/fijkplayer

一、 引入 pubspec.yaml 文件写入

dependencies:
fijkplayer: ^0.8.8


二、 使用的模块头部导入
import 'package:fijkplayer/fijkplayer.dart';​


三、 上代码

import 'dart:async';
import 'package:defensor/common/api.dart';
import 'package:defensor/service/device_service.dart';
import 'package:defensor/utils/aperture/aperture.dart';
import 'package:defensor/views/home/camera_settings.dart';
import 'package:fijkplayer/fijkplayer.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

import 'gallery/gallery.dart';

class Preview extends StatefulWidget {
Preview({Key key}) : super(key: key);

@override
_PreviewState createState() => _PreviewState();
}

class _PreviewState extends State with SingleTickerProviderStateMixin {
/// 视频控制器
final FijkPlayer player = FijkPlayer();

/// 动画控制器
AnimationController animationController;

@override
void initState() {

loadSdInfo();
loadPreview();

takePictureAnimation();
super.initState();
}

@override
void dispose() {
DeviceService.workmodecmd(cmd: 'stop');
// 退出时移除视频控制器
player.release();
animationController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: ConstrainedBox(
constraints: BoxConstraints.expand(),
child: Stack(
alignment: Alignment.center,
children: [
FijkView(
color: Colors.black,
player: player,
// fit: FijkFit.contain,
// panelBuilder: fijkPanel2Builder(),
),
SizedBox(
width: 600.0, //MediaQuery.of(context).size.width,
height: 610.0, //MediaQuery.of(context).size.height,
child: Aperture(
animationController: animationController,
child: Container(),
),
),
Positioned(
// 退出
top: 38,
left: 0,
child: BackButton(color: Colors.white),
),
Positioned(
top: 30,
right: 0,
// 全屏
child: CupertinoButton(
child: Container(
width: 20,
height: 20,
child: Image.asset('assets/images/quanping.png')),
onPressed: () {
player.enterFullScreen();
}),
),
Positioned(
bottom: 30,
// 拍照
child: CupertinoButton(
child: Container(
width: 50,
height: 50,
child: Image.asset('assets/images/paizhao.png')),
onPressed: () => takePicture()),
),
Positioned(
bottom: 30,
right: 30,
// 设置
child: CupertinoButton(
child: Container(
width: 30,
height: 30,
child: Image.asset('assets/images/shezhi.png')),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CameraSettings(),
),
);
}),
),
Positioned(
bottom: 30,
left: 30,
// 相册
child: CupertinoButton(
child: Container(
width: 30,
height: 30,
child: Image.asset('assets/images/xiangce.png')),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Gallery(),
),
);
}),
),
],
),
),
);
}

/// 加载实时预览
loadPreview() async {
// 解决 rtmp 延迟长的问题, 目前 1 秒内延迟
player.setOption(FijkOption.playerCategory, 'start-on-prepared', 0);
player.setOption(FijkOption.formatCategory, 'http-detect-range-support', 0);

player.setOption(FijkOption.codecCategory, 'skip_loop_filter', 48);
player.setOption(FijkOption.codecCategory, 'skip_loop_filter', 8);
player.setOption(1, "analyzemaxduration", 100);
player.setOption(1, "probesize", 10240);
player.setOption(1, "flush_packets", 1);
player.setOption(4, "packet-buffering", 0);
player.setOption(4, "framedrop", 1);

// 支持硬解 1:开启 O:关闭
player.setOption(FijkOption.playerCategory, "mediacodec-hevc", 1);
// 设置播放前的探测时间 1,达到首屏秒开效果
player.setOption(FijkOption.formatCategory, "analyzeduration", 1);

// /**
// * 播放延时的解决方案
// */
// // 如果是rtsp协议,可以优先用tcp(默认是用udp)
// player.setOption(FijkOption.formatCategory, "rtsp_transport", "tcp");
// // 设置播放前的最大探测时间 (100未测试是否是最佳值)
// player.setOption(FijkOption.formatCategory, "analyzemaxduration", 100);
// // 每处理一个packet之后刷新io上下文
// player.setOption(FijkOption.formatCategory, "flush_packets", 1);
// // 需要准备好后自动播放
// player.setOption(FijkOption.playerCategory, "start-on-prepared", 1);
// // 不额外优化(使能非规范兼容优化,默认值0 )
// player.setOption(FijkOption.playerCategory, "fast", 1);
// // 是否开启预缓冲,一般直播项目会开启,达到秒开的效果,不过带来了播放丢帧卡顿的体验
// player.setOption(FijkOption.playerCategory, "packet-buffering", 0);
// // 自动旋屏
// player.setOption(FijkOption.playerCategory, "mediacodec-auto-rotate", 0);
// // 处理分辨率变化
// player.setOption(FijkOption.playerCategory, "mediacodec-handle-resolution-change", 0);
// // 最大缓冲大小,单位kb
// player.setOption(FijkOption.formatCategory, "max-buffer-size", 0);
// // 默认最小帧数2
// player.setOption(FijkOption.playerCategory, "min-frames", 2);
// // 最大缓存时长
// player.setOption(FijkOption.playerCategory, "max_cached_duration", 3); //300
// // 是否限制输入缓存数
// player.setOption(FijkOption.playerCategory, "infbuf", 1);
// // 缩短播放的rtmp视频延迟在1s内
// player.setOption(FijkOption.formatCategory, "fflags", "nobuffer");
// // 播放前的探测Size,默认是1M, 改小一点会出画面更快
// player.setOption(FijkOption.formatCategory, "probesize", 200); //1024L)
// // 播放重连次数
// player.setOption(FijkOption.playerCategory,"reconnect", 5);
// // TODO:
// player.setOption(FijkOption.formatCategory, "http-detect-range-support", 0);
// // 设置是否开启环路过滤: 0开启,画面质量高,解码开销大,48关闭,画面质量差点,解码开销小
// player.setOption(FijkOption.codecCategory, "skip_loop_filter", 0);
// // 跳过帧 ??
// player.setOption(FijkOption.codecCategory, "skip_frame", 0);
// // 视频帧处理不过来的时候丢弃一些帧达到同步的效果
// player.setOption(FijkOption.playerCategory, "framedrop", 5);

await player.setOption(FijkOption.hostCategory, "request-screen-on", 1);
await player.setOption(FijkOption.hostCategory, "request-audio-focus", 1);
// 设置播放源
await player.setDataSource(Api.livestream, autoPlay: true);
// 全屏
// player.enterFullScreen();
}

/// 拍照
takePicture() async {
Timer.run(() async {
var result = await DeviceService.workmodecmd(cmd: 'trigger');
print('result $result');
if (result) {
Fluttertoast.showToast(msg: '拍照成功');
} else {
Fluttertoast.showToast(msg: '拍照不成功');
}
});
// 黑屏一下
Fluttertoast.showToast(
msg: '拍照', gravity: ToastGravity.TOP, toastLength: Toast.LENGTH_LONG);
setState(() {
// !启用动画效果
animationController.forward();
});
}

/// 相册快门动画
takePictureAnimation() {
animationController = AnimationController(
// !初始动画周期为13秒
vsync: this,
duration: Duration(milliseconds: 1300));

animationController.addStatusListener((status) {
// ! 快门(动画区)合并时重启动画
if (status == AnimationStatus.completed) {
Future.delayed(const Duration(milliseconds: 400), () {
animationController.reverse();
// animationController.stop();
});
// ! 快门(动画区)最大化张开时停止动画
} else if (status == AnimationStatus.dismissed) {
Future.delayed(const Duration(milliseconds: 400), () {
// animationController.forward();
animationController.stop();
});
}
});
// !Starts running this animation in reverse (towards the beginning).
// !将动画至于开始状态(未执行)
// !如果设置成forward将自动开启动画效果
animationController.reverse();
// animationController.dispose();
}

/// 获取 sd 卡的提示信息
Future loadSdInfo() async {
String sdInfo = await DeviceService.getsdpromptinfo();
if (sdInfo == null) {
print('设备没有连接成功');
return Fluttertoast.showToast(
msg: '设备没有连接成功',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.TOP);
}
Fluttertoast.showToast(
msg: sdInfo, toastLength: Toast.LENGTH_LONG, gravity: ToastGravity.TOP);
}
}




★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论