提交 0b0eb747 authored 作者: kongdywang's avatar kongdywang

1. Fix the issue where customers experience exceptions when using certain…

1. Fix the issue where customers experience exceptions when using certain interfaces of the live or VOD player that has been released under high-intensity usage scenarios on the Flutter side. 2. Fix the issue where the texture ID cannot be refreshed in some scenarios with the txplayer_widget. 3. Fix the issue where the controller cannot be refreshed in some scenarios with the superplayerWidget.
上级 0c27faf4
...@@ -144,6 +144,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -144,6 +144,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// 参考: [PlayType.LIVE_RTMP] ... /// 参考: [PlayType.LIVE_RTMP] ...
@deprecated @deprecated
Future<bool> play(String url, {int? playType}) async { Future<bool> play(String url, {int? playType}) async {
if (_isNeedDisposed) return false;
return await startLivePlay(url, playType: playType); return await startLivePlay(url, playType: playType);
} }
...@@ -168,6 +169,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -168,6 +169,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// ///
/// ///
Future<bool> startLivePlay(String url, {@deprecated int? playType}) async { Future<bool> startLivePlay(String url, {@deprecated int? playType}) async {
if (_isNeedDisposed) return false;
await _initPlayer.future; await _initPlayer.future;
await _createTexture.future; await _createTexture.future;
_changeState(TXPlayerState.buffering); _changeState(TXPlayerState.buffering);
...@@ -214,6 +216,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -214,6 +216,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// 视频是否处于正在播放中 /// 视频是否处于正在播放中
@override @override
Future<bool> isPlaying() async { Future<bool> isPlaying() async {
if (_isNeedDisposed) return false;
await _initPlayer.future; await _initPlayer.future;
BoolMsg boolMsg = await _livePlayerApi.isPlaying(PlayerMsg()..playerId = _playerId); BoolMsg boolMsg = await _livePlayerApi.isPlaying(PlayerMsg()..playerId = _playerId);
return boolMsg.value ?? false; return boolMsg.value ?? false;
...@@ -339,6 +342,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -339,6 +342,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
@override @override
Future<int> enterPictureInPictureMode( Future<int> enterPictureInPictureMode(
{String? backIconForAndroid, String? playIconForAndroid, String? pauseIconForAndroid, String? forwardIconForAndroid}) async { {String? backIconForAndroid, String? playIconForAndroid, String? pauseIconForAndroid, String? forwardIconForAndroid}) async {
if (_isNeedDisposed) return -1;
await _initPlayer.future; await _initPlayer.future;
if (defaultTargetPlatform == TargetPlatform.android) { if (defaultTargetPlatform == TargetPlatform.android) {
IntMsg intMsg = await _livePlayerApi.enterPictureInPictureMode(PipParamsPlayerMsg() IntMsg intMsg = await _livePlayerApi.enterPictureInPictureMode(PipParamsPlayerMsg()
...@@ -361,6 +365,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -361,6 +365,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// 退出画中画,如果该播放器处于画中画模式 /// 退出画中画,如果该播放器处于画中画模式
@override @override
Future<void> exitPictureInPictureMode() async { Future<void> exitPictureInPictureMode() async {
if (_isNeedDisposed) return;
if (defaultTargetPlatform == TargetPlatform.android) { if (defaultTargetPlatform == TargetPlatform.android) {
await _livePlayerApi.exitPictureInPictureMode(PlayerMsg() await _livePlayerApi.exitPictureInPictureMode(PlayerMsg()
..playerId = _playerId); ..playerId = _playerId);
...@@ -383,6 +388,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -383,6 +388,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// 指定接收 SEI 消息的 payloadType,支持 5、242、243,请与发送端的 payloadType 保持一致。 /// 指定接收 SEI 消息的 payloadType,支持 5、242、243,请与发送端的 payloadType 保持一致。
/// ///
Future<int> enableReceiveSeiMessage(bool isEnabled, int payloadType) async { Future<int> enableReceiveSeiMessage(bool isEnabled, int payloadType) async {
if (_isNeedDisposed) return -1;
return await _livePlayerApi.enableReceiveSeiMessage(PlayerMsg(playerId: _playerId), return await _livePlayerApi.enableReceiveSeiMessage(PlayerMsg(playerId: _playerId),
isEnabled, payloadType); isEnabled, payloadType);
} }
...@@ -395,6 +401,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -395,6 +401,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// @param isShow 是否显示。default:NO。 /// @param isShow 是否显示。default:NO。
/// ///
Future<void> showDebugView(bool isShow) async { Future<void> showDebugView(bool isShow) async {
if (_isNeedDisposed) return;
await _livePlayerApi.showDebugView(PlayerMsg(playerId: _playerId), isShow); await _livePlayerApi.showDebugView(PlayerMsg(playerId: _playerId), isShow);
} }
...@@ -418,6 +425,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -418,6 +425,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// - -2: 操作失败,key 不允许为 nil。 /// - -2: 操作失败,key 不允许为 nil。
/// ///
Future<int> setProperty(String key, Object value) async { Future<int> setProperty(String key, Object value) async {
if (_isNeedDisposed) return -1;
return await _livePlayerApi.setProperty(PlayerMsg(playerId: _playerId), key, value); return await _livePlayerApi.setProperty(PlayerMsg(playerId: _playerId), key, value);
} }
...@@ -427,6 +435,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -427,6 +435,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// 获取码流信息 /// 获取码流信息
/// ///
Future<List<FSteamInfo>> getSupportedBitrate() async { Future<List<FSteamInfo>> getSupportedBitrate() async {
if (_isNeedDisposed) return [];
ListMsg listMsg = await _livePlayerApi.getSupportedBitrate(PlayerMsg(playerId: _playerId)); ListMsg listMsg = await _livePlayerApi.getSupportedBitrate(PlayerMsg(playerId: _playerId));
List<FSteamInfo> steamList = []; List<FSteamInfo> steamList = [];
if (null != listMsg.value) { if (null != listMsg.value) {
...@@ -459,6 +468,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -459,6 +468,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
/// - -3: 播放器处于播放状态,不支持修改缓存策略。 /// - -3: 播放器处于播放状态,不支持修改缓存策略。
/// ///
Future<int> setCacheParams(double minTime, double maxTime) async { Future<int> setCacheParams(double minTime, double maxTime) async {
if (_isNeedDisposed) return -1;
return await _livePlayerApi.setCacheParams(PlayerMsg(playerId: _playerId), minTime, maxTime); return await _livePlayerApi.setCacheParams(PlayerMsg(playerId: _playerId), minTime, maxTime);
} }
......
...@@ -3,9 +3,8 @@ part of SuperPlayer; ...@@ -3,9 +3,8 @@ part of SuperPlayer;
class TXPlayerVideo extends StatefulWidget { class TXPlayerVideo extends StatefulWidget {
final TXPlayerController controller; final TXPlayerController controller;
final Stream<TXPlayerHolder>? playerStream;
TXPlayerVideo({required this.controller, this.playerStream}); TXPlayerVideo({required this.controller});
@override @override
TXPlayerVideoState createState() => TXPlayerVideoState(); TXPlayerVideoState createState() => TXPlayerVideoState();
...@@ -16,55 +15,31 @@ class TXPlayerVideoState extends State<TXPlayerVideo> { ...@@ -16,55 +15,31 @@ class TXPlayerVideoState extends State<TXPlayerVideo> {
int _textureId = -1; int _textureId = -1;
StreamSubscription? streamSubscription; StreamSubscription? streamSubscription;
late TXPlayerController controller;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_obtainTextureId();
controller = widget.controller;
_checkStreamListen();
_resetControllerLink();
} }
void _checkStreamListen() { @override
if(null != streamSubscription) { void didUpdateWidget(covariant TXPlayerVideo oldWidget) {
streamSubscription!.cancel(); super.didUpdateWidget(oldWidget);
} _obtainTextureId();
streamSubscription = widget.playerStream?.listen((event) {
controller = event.controller;
_resetControllerLink();
});
} }
void _resetControllerLink() async { void _obtainTextureId() async {
int remainTextureId = await controller.textureId; int remainTextureId = await widget.controller.textureId;
if (remainTextureId >= 0) { if (_textureId != remainTextureId) {
if (remainTextureId != _textureId) {
_refreshTextureId(remainTextureId);
}
} else {
setState(() { setState(() {
_textureId = -1; _textureId = remainTextureId;
}); });
controller.textureId.then((newTextureId) {
if (_textureId != newTextureId) {
_refreshTextureId(newTextureId);
}
});
}
}
void _refreshTextureId(int textureId) {
LogUtils.d(TAG, "_textureId = $textureId");
_textureId = textureId;
if (mounted) {
setState(() {});
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
TXPlayerController controller = widget.controller;
if ((defaultTargetPlatform == TargetPlatform.android) && if ((defaultTargetPlatform == TargetPlatform.android) &&
(controller.resizeVideoHeight! > 0 && controller.resizeVideoWidth! > 0)) { (controller.resizeVideoHeight! > 0 && controller.resizeVideoWidth! > 0)) {
return _textureId == -1 return _textureId == -1
......
...@@ -177,6 +177,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX ...@@ -177,6 +177,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
/// @param url : 视频播放地址 video playback address /// @param url : 视频播放地址 video playback address
/// return 是否播放成功 if play successfully /// return 是否播放成功 if play successfully
Future<bool> startVodPlay(String url) async { Future<bool> startVodPlay(String url) async {
if (_isNeedDisposed) return false;
await _initPlayer.future; await _initPlayer.future;
await _createTexture.future; await _createTexture.future;
_changeState(TXPlayerState.buffering); _changeState(TXPlayerState.buffering);
...@@ -203,6 +204,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX ...@@ -203,6 +204,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
/// @params : see[TXPlayInfoParams] /// @params : see[TXPlayInfoParams]
/// return 是否播放成功 if play successful /// return 是否播放成功 if play successful
Future<void> startVodPlayWithParams(TXPlayInfoParams params) async { Future<void> startVodPlayWithParams(TXPlayInfoParams params) async {
if (_isNeedDisposed) return;
await _initPlayer.future; await _initPlayer.future;
await _createTexture.future; await _createTexture.future;
_changeState(TXPlayerState.buffering); _changeState(TXPlayerState.buffering);
...@@ -270,6 +272,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX ...@@ -270,6 +272,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
/// 视频是否处于正在播放中 /// 视频是否处于正在播放中
@override @override
Future<bool> isPlaying() async { Future<bool> isPlaying() async {
if (_isNeedDisposed) return false;
await _initPlayer.future; await _initPlayer.future;
BoolMsg boolMsg = await _vodPlayerApi.isPlaying(PlayerMsg()..playerId = _playerId); BoolMsg boolMsg = await _vodPlayerApi.isPlaying(PlayerMsg()..playerId = _playerId);
return boolMsg.value ?? false; return boolMsg.value ?? false;
......
...@@ -28,7 +28,6 @@ class SuperPlayerController { ...@@ -28,7 +28,6 @@ class SuperPlayerController {
List<TXTrackInfo>? subtitleTrackInfoList; List<TXTrackInfo>? subtitleTrackInfoList;
TXVodSubtitleData? currentSubtitleData; TXVodSubtitleData? currentSubtitleData;
TXSubtitleRenderModel? _currentSubtitleRenderModel; TXSubtitleRenderModel? _currentSubtitleRenderModel;
StreamController<TXPlayerHolder> playerStreamController = StreamController.broadcast();
SuperPlayerState playerState = SuperPlayerState.INIT; SuperPlayerState playerState = SuperPlayerState.INIT;
SuperPlayerType playerType = SuperPlayerType.VOD; SuperPlayerType playerType = SuperPlayerType.VOD;
FTXVodPlayConfig _vodConfig = FTXVodPlayConfig(); FTXVodPlayConfig _vodConfig = FTXVodPlayConfig();
...@@ -557,7 +556,6 @@ class SuperPlayerController { ...@@ -557,7 +556,6 @@ class SuperPlayerController {
void _updatePlayerType(SuperPlayerType type) { void _updatePlayerType(SuperPlayerType type) {
if (playerType != type) { if (playerType != type) {
playerType = type; playerType = type;
updatePlayerView();
_observer?.onPlayerTypeChange(type); _observer?.onPlayerTypeChange(type);
if (type == SuperPlayerType.VOD) { if (type == SuperPlayerType.VOD) {
_livePlayerController.exitPictureInPictureMode(); _livePlayerController.exitPictureInPictureMode();
...@@ -565,16 +563,6 @@ class SuperPlayerController { ...@@ -565,16 +563,6 @@ class SuperPlayerController {
} }
} }
void updatePlayerView() async {
TXPlayerController controller = getCurrentController();
TXPlayerHolder model = TXPlayerHolder(controller);
playerStreamController.sink.add(model);
}
Stream<TXPlayerHolder> getPlayerStream() {
return playerStreamController.stream;
}
/// Get the current controller being used /// Get the current controller being used
TXPlayerController getCurrentController() { TXPlayerController getCurrentController() {
TXPlayerController controller; TXPlayerController controller;
...@@ -742,7 +730,6 @@ class SuperPlayerController { ...@@ -742,7 +730,6 @@ class SuperPlayerController {
} }
// Remove the event listener for the widget. // Remove the event listener for the widget.
_observer?.onDispose(); _observer?.onDispose();
playerStreamController.close();
} }
/// return true: executed exit full screen and other operations, consumed the return event. return false: did not consume the event. /// return true: executed exit full screen and other operations, consumed the return event. return false: did not consume the event.
......
...@@ -163,6 +163,12 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs ...@@ -163,6 +163,12 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs
_initPlayerState(); _initPlayerState();
} }
@override
void didUpdateWidget(covariant SuperPlayerView oldWidget) {
super.didUpdateWidget(oldWidget);
_playController = widget._controller;
}
void _registerObserver() { void _registerObserver() {
_playController._observer = _SuperPlayerObserver(() { _playController._observer = _SuperPlayerObserver(() {
// preparePlayVideo // preparePlayVideo
...@@ -581,10 +587,10 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs ...@@ -581,10 +587,10 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs
child: widget.renderMode == SuperPlayerRenderMode.ADJUST_RESOLUTION ? child: widget.renderMode == SuperPlayerRenderMode.ADJUST_RESOLUTION ?
AspectRatio( AspectRatio(
aspectRatio: _aspectRatio, aspectRatio: _aspectRatio,
child: TXPlayerVideo(controller: _playController.getCurrentController(), playerStream: _playController.getPlayerStream())) child: TXPlayerVideo(controller: _playController.getCurrentController()))
: SizedBox( : SizedBox(
child: TXPlayerVideo( child: TXPlayerVideo(
controller: _playController.getCurrentController(), playerStream: _playController.getPlayerStream()), controller: _playController.getCurrentController()),
) )
), ),
); );
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论