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