提交 525c9243 authored 作者: kongdywang's avatar kongdywang

pipController add exit callback & fix bug

上级 86800444
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import android.os.Bundle; import android.os.Bundle;
...@@ -40,6 +41,9 @@ public class CommonUtil { ...@@ -40,6 +41,9 @@ public class CommonUtil {
return param; return param;
} }
/**
* 通过宽高获得对应的缓存视频清晰度
*/
public static int getCacheVideoQuality(Integer width, Integer height) { public static int getCacheVideoQuality(Integer width, Integer height) {
if (width == null || height == null) { if (width == null || height == null) {
return TXVodDownloadDataSource.QUALITY_FLU; return TXVodDownloadDataSource.QUALITY_FLU;
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import android.content.Context; import android.content.Context;
...@@ -18,7 +19,7 @@ import java.util.List; ...@@ -18,7 +19,7 @@ import java.util.List;
*/ */
public class FTXAudioManager { public class FTXAudioManager {
private final static String TAG = "FTXAudioManager"; private static final String TAG = "FTXAudioManager";
private AudioManager mAudioManager; private AudioManager mAudioManager;
private AudioFocusRequest mFocusRequest; private AudioFocusRequest mFocusRequest;
...@@ -116,6 +117,9 @@ public class FTXAudioManager { ...@@ -116,6 +117,9 @@ public class FTXAudioManager {
} }
} }
/**
* 请求获取音频焦点
*/
public void requestAudioFocus() { public void requestAudioFocus() {
int result; int result;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
...@@ -141,7 +145,7 @@ public class FTXAudioManager { ...@@ -141,7 +145,7 @@ public class FTXAudioManager {
} }
public void addAudioFocusChangedListener(AudioFocusChangeListener listener) { public void addAudioFocusChangedListener(AudioFocusChangeListener listener) {
if(!mAudioFocusListeners.contains(listener)) { if (!mAudioFocusListeners.contains(listener)) {
mAudioFocusListeners.add(listener); mAudioFocusListeners.add(listener);
} }
} }
...@@ -151,19 +155,20 @@ public class FTXAudioManager { ...@@ -151,19 +155,20 @@ public class FTXAudioManager {
} }
void onAudioFocusPause() { void onAudioFocusPause() {
for(AudioFocusChangeListener listener : mAudioFocusListeners) { for (AudioFocusChangeListener listener : mAudioFocusListeners) {
listener.onAudioFocusPause(); listener.onAudioFocusPause();
} }
} }
void onAudioFocusPlay() { void onAudioFocusPlay() {
for(AudioFocusChangeListener listener : mAudioFocusListeners) { for (AudioFocusChangeListener listener : mAudioFocusListeners) {
listener.onAudioFocusPlay(); listener.onAudioFocusPlay();
} }
} }
interface AudioFocusChangeListener { interface AudioFocusChangeListener {
void onAudioFocusPause(); void onAudioFocusPause();
void onAudioFocusPlay(); void onAudioFocusPlay();
} }
} }
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/** /**
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import android.os.Bundle; import android.os.Bundle;
...@@ -29,18 +30,23 @@ import io.flutter.plugin.common.MethodChannel; ...@@ -29,18 +30,23 @@ import io.flutter.plugin.common.MethodChannel;
*/ */
public class FTXDownloadManager implements MethodChannel.MethodCallHandler, ITXVodDownloadListener { public class FTXDownloadManager implements MethodChannel.MethodCallHandler, ITXVodDownloadListener {
private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding; private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding;
final private MethodChannel mMethodChannel; private final MethodChannel mMethodChannel;
private final EventChannel mEventChannel; private final EventChannel mEventChannel;
final private FTXPlayerEventSink mEventSink = new FTXPlayerEventSink(); private final FTXPlayerEventSink mEventSink = new FTXPlayerEventSink();
private Handler mMainHandler; private Handler mMainHandler;
/**
* 视频下载管理
*/
public FTXDownloadManager(FlutterPlugin.FlutterPluginBinding flutterPluginBinding) { public FTXDownloadManager(FlutterPlugin.FlutterPluginBinding flutterPluginBinding) {
mFlutterPluginBinding = flutterPluginBinding; mFlutterPluginBinding = flutterPluginBinding;
mMainHandler = new Handler(mFlutterPluginBinding.getApplicationContext().getMainLooper()); mMainHandler = new Handler(mFlutterPluginBinding.getApplicationContext().getMainLooper());
mMethodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent.com/txvodplayer/download/api"); mMethodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(),
"cloud.tencent.com/txvodplayer/download/api");
mMethodChannel.setMethodCallHandler(this); mMethodChannel.setMethodCallHandler(this);
mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent.com/txvodplayer/download/event"); mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
"cloud.tencent.com/txvodplayer/download/event");
mEventChannel.setStreamHandler(new EventChannel.StreamHandler() { mEventChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override @Override
public void onListen(Object o, EventChannel.EventSink eventSink) { public void onListen(Object o, EventChannel.EventSink eventSink) {
...@@ -92,8 +98,8 @@ public class FTXDownloadManager implements MethodChannel.MethodCallHandler, ITXV ...@@ -92,8 +98,8 @@ public class FTXDownloadManager implements MethodChannel.MethodCallHandler, ITXV
if (!TextUtils.isEmpty(videoUrl)) { if (!TextUtils.isEmpty(videoUrl)) {
TXVodDownloadManager.getInstance().startDownloadUrl(videoUrl, userName); TXVodDownloadManager.getInstance().startDownloadUrl(videoUrl, userName);
} else if (null != appId && null != fileId) { } else if (null != appId && null != fileId) {
TXVodDownloadDataSource dataSource = new TXVodDownloadDataSource(appId, fileId, optQuality(quality), pSign, TXVodDownloadDataSource dataSource =
userName); new TXVodDownloadDataSource(appId, fileId, optQuality(quality), pSign, userName);
TXVodDownloadManager.getInstance().startDownload(dataSource); TXVodDownloadManager.getInstance().startDownload(dataSource);
} }
result.success(null); result.success(null);
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
/** /**
...@@ -41,7 +42,7 @@ public class FTXEvent { ...@@ -41,7 +42,7 @@ public class FTXEvent {
*/ */
public static final String PIP_CHANNEL_NAME = "cloud.tencent.com/playerPlugin/componentEvent"; public static final String PIP_CHANNEL_NAME = "cloud.tencent.com/playerPlugin/componentEvent";
// pip广播action // pip广播action
public final static String ACTION_PIP_PLAY_CONTROL = "vodPlayControl"; public static final String ACTION_PIP_PLAY_CONTROL = "vodPlayControl";
// pip 操作 // pip 操作
public static final String EXTRA_NAME_PLAY_OP = "vodPlayOp"; public static final String EXTRA_NAME_PLAY_OP = "vodPlayOp";
// pip需要操作的播放器 // pip需要操作的播放器
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import android.app.Activity; import android.app.Activity;
...@@ -29,15 +30,15 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method ...@@ -29,15 +30,15 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
private static final String TAG = "FTXLivePlayer"; private static final String TAG = "FTXLivePlayer";
private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding; private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding;
final private MethodChannel mMethodChannel; private final MethodChannel mMethodChannel;
private final EventChannel mEventChannel; private final EventChannel mEventChannel;
private final EventChannel mNetChannel; private final EventChannel mNetChannel;
private SurfaceTexture mSurfaceTexture; private SurfaceTexture mSurfaceTexture;
private Surface mSurface; private Surface mSurface;
final private FTXPlayerEventSink mEventSink = new FTXPlayerEventSink(); private final FTXPlayerEventSink mEventSink = new FTXPlayerEventSink();
final private FTXPlayerEventSink mNetStatusSink = new FTXPlayerEventSink(); private final FTXPlayerEventSink mNetStatusSink = new FTXPlayerEventSink();
private TXLivePlayer mLivePlayer; private TXLivePlayer mLivePlayer;
private static final int Uninitialized = -101; private static final int Uninitialized = -101;
...@@ -46,6 +47,9 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method ...@@ -46,6 +47,9 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
private TextureRegistry.SurfaceTextureEntry mSurfaceTextureEntry; private TextureRegistry.SurfaceTextureEntry mSurfaceTextureEntry;
private Activity mActivity; private Activity mActivity;
private int mSurfaceWidth = 0;
private int mSurfaceHeight = 0;
private final FTXPIPManager mPipManager; private final FTXPIPManager mPipManager;
private FTXPIPManager.PipParams mPipParams; private FTXPIPManager.PipParams mPipParams;
private VideoModel mVideoModel; private VideoModel mVideoModel;
...@@ -54,12 +58,15 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method ...@@ -54,12 +58,15 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
public void onPipResult(PipResult result) { public void onPipResult(PipResult result) {
// 启动pip的时候,当前player已经暂停,pip退出之后,如果退出的时候pip还处于播放状态,那么当前player也置为播放状态 // 启动pip的时候,当前player已经暂停,pip退出之后,如果退出的时候pip还处于播放状态,那么当前player也置为播放状态
boolean isPipPlaying = result.isPlaying(); boolean isPipPlaying = result.isPlaying();
if(isPipPlaying) { if (isPipPlaying) {
resume(); resume();
} }
} }
}; };
/**
* 直播播放器
*/
public FTXLivePlayer(FlutterPlugin.FlutterPluginBinding flutterPluginBinding, Activity activity, public FTXLivePlayer(FlutterPlugin.FlutterPluginBinding flutterPluginBinding, Activity activity,
FTXPIPManager pipManager) { FTXPIPManager pipManager) {
super(); super();
...@@ -73,10 +80,12 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method ...@@ -73,10 +80,12 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
mSurfaceTexture = mSurfaceTextureEntry.surfaceTexture(); mSurfaceTexture = mSurfaceTextureEntry.surfaceTexture();
mSurface = new Surface(mSurfaceTexture); mSurface = new Surface(mSurfaceTexture);
mMethodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent.com/txliveplayer/" + super.getPlayerId()); mMethodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(),
"cloud.tencent.com/txliveplayer/" + super.getPlayerId());
mMethodChannel.setMethodCallHandler(this); mMethodChannel.setMethodCallHandler(this);
mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent.com/txliveplayer/event/" + super.getPlayerId()); mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
"cloud.tencent.com/txliveplayer/event/" + super.getPlayerId());
mEventChannel.setStreamHandler(new EventChannel.StreamHandler() { mEventChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override @Override
public void onListen(Object o, EventChannel.EventSink eventSink) { public void onListen(Object o, EventChannel.EventSink eventSink) {
...@@ -89,7 +98,8 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method ...@@ -89,7 +98,8 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
} }
}); });
mNetChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent.com/txliveplayer/net/" + super.getPlayerId()); mNetChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
"cloud.tencent.com/txliveplayer/net/" + super.getPlayerId());
mNetChannel.setStreamHandler(new EventChannel.StreamHandler() { mNetChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override @Override
public void onListen(Object o, EventChannel.EventSink eventSink) { public void onListen(Object o, EventChannel.EventSink eventSink) {
...@@ -242,11 +252,11 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method ...@@ -242,11 +252,11 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
mPipParams.setIsPlaying(isPlaying()); mPipParams.setIsPlaying(isPlaying());
int pipResult = mPipManager.enterPip(mPipParams, mVideoModel); int pipResult = mPipManager.enterPip(mPipParams, mVideoModel);
// 启动成功之后,暂停当前界面视频 // 启动成功之后,暂停当前界面视频
if(pipResult == FTXEvent.NO_ERROR) { if (pipResult == FTXEvent.NO_ERROR) {
pause(); pause();
} }
result.success(pipResult); result.success(pipResult);
} else if(call.method.equals("exitPictureInPictureMode")) { } else if (call.method.equals("exitPictureInPictureMode")) {
mPipManager.exitPip(); mPipManager.exitPip();
result.success(null); result.success(null);
} else if (call.method.equals("setConfig")) { } else if (call.method.equals("setConfig")) {
...@@ -267,8 +277,6 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method ...@@ -267,8 +277,6 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
return mSurfaceTextureEntry == null ? -1 : mSurfaceTextureEntry.id(); return mSurfaceTextureEntry == null ? -1 : mSurfaceTextureEntry.id();
} }
private int mSurfaceWidth, mSurfaceHeight = 0;
int startLivePlay(String url, int type) { int startLivePlay(String url, int type) {
Log.d(TAG, "startLivePlay:"); Log.d(TAG, "startLivePlay:");
mVideoModel.setVideoUrl(url); mVideoModel.setVideoUrl(url);
......
...@@ -77,6 +77,7 @@ public class FTXPIPManager { ...@@ -77,6 +77,7 @@ public class FTXPIPManager {
}; };
/** /**
* 画中画管理
* @param mTxAudioManager 音频管理,用于画中画模式下请求音频焦点 * @param mTxAudioManager 音频管理,用于画中画模式下请求音频焦点
* @param activityBinding activityBinding * @param activityBinding activityBinding
* @param flutterAssets flutter资源管理 * @param flutterAssets flutter资源管理
...@@ -159,6 +160,9 @@ public class FTXPIPManager { ...@@ -159,6 +160,9 @@ public class FTXPIPManager {
} }
} }
/**
* 设备是否支持画中画
*/
public int isSupportDevice() { public int isSupportDevice() {
int pipResult = FTXEvent.NO_ERROR; int pipResult = FTXEvent.NO_ERROR;
Activity activity = mActivityBinding.getActivity(); Activity activity = mActivityBinding.getActivity();
...@@ -176,8 +180,8 @@ public class FTXPIPManager { ...@@ -176,8 +180,8 @@ public class FTXPIPManager {
} }
} else { } else {
pipResult = FTXEvent.ERROR_PIP_LOWER_VERSION; pipResult = FTXEvent.ERROR_PIP_LOWER_VERSION;
Log.e(TAG, "enterPip failed,because android version is too low,Minimum supported version is android " + Log.e(TAG, "enterPip failed,because android version is too low,Minimum supported version is android "
"24,but current is " + Build.VERSION.SDK_INT); + "24,but current is " + Build.VERSION.SDK_INT);
} }
} else { } else {
pipResult = FTXEvent.ERROR_PIP_ACTIVITY_DESTROYED; pipResult = FTXEvent.ERROR_PIP_ACTIVITY_DESTROYED;
...@@ -259,6 +263,7 @@ public class FTXPIPManager { ...@@ -259,6 +263,7 @@ public class FTXPIPManager {
private float mCurrentPlayTime = 0; private float mCurrentPlayTime = 0;
/** /**
* 画中画参数
* @param mPlayBackAssetPath 回退按钮图片资源路径,传空则使用系统默认图标, 地址必须经过toAndroidPath转换 * @param mPlayBackAssetPath 回退按钮图片资源路径,传空则使用系统默认图标, 地址必须经过toAndroidPath转换
* @param mPlayResumeAssetPath 播放按钮图片资源路径,传空则使用系统默认图标, 地址必须经过toAndroidPath转换 * @param mPlayResumeAssetPath 播放按钮图片资源路径,传空则使用系统默认图标, 地址必须经过toAndroidPath转换
* @param mPlayPauseAssetPath 暂停按钮图片资源路径,传空则使用系统默认图标, 地址必须经过toAndroidPath转换 * @param mPlayPauseAssetPath 暂停按钮图片资源路径,传空则使用系统默认图标, 地址必须经过toAndroidPath转换
...@@ -329,9 +334,11 @@ public class FTXPIPManager { ...@@ -329,9 +334,11 @@ public class FTXPIPManager {
this.mCurrentPlayTime = mCurrentPlayTime; this.mCurrentPlayTime = mCurrentPlayTime;
} }
/**
* 构造画中画参数
*/
@RequiresApi(api = VERSION_CODES.O) @RequiresApi(api = VERSION_CODES.O)
public PictureInPictureParams buildParams(Activity activity) { public PictureInPictureParams buildParams(Activity activity) {
PictureInPictureParams.Builder mPipParams = new Builder();
List<RemoteAction> actions = new ArrayList<>(); List<RemoteAction> actions = new ArrayList<>();
// play back // play back
if (mIsNeedPlayBack) { if (mIsNeedPlayBack) {
...@@ -373,6 +380,7 @@ public class FTXPIPManager { ...@@ -373,6 +380,7 @@ public class FTXPIPManager {
actions.add(nextAction); actions.add(nextAction);
} }
PictureInPictureParams.Builder mPipParams = new Builder();
mPipParams.setActions(actions); mPipParams.setActions(actions);
return mPipParams.build(); return mPipParams.build();
} }
...@@ -404,7 +412,8 @@ public class FTXPIPManager { ...@@ -404,7 +412,8 @@ public class FTXPIPManager {
Bitmap iconBitmap = BitmapFactory.decodeStream(activity.getAssets().open(path)); Bitmap iconBitmap = BitmapFactory.decodeStream(activity.getAssets().open(path));
return Icon.createWithBitmap(iconBitmap); return Icon.createWithBitmap(iconBitmap);
} }
} catch (IOException ignored) { } catch (IOException e) {
Log.getStackTraceString(e);
} }
return Icon.createWithResource(activity, defaultResId); return Icon.createWithResource(activity, defaultResId);
} }
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -21,13 +22,17 @@ public class FTXPlayerEventSink implements EventChannel.EventSink { ...@@ -21,13 +22,17 @@ public class FTXPlayerEventSink implements EventChannel.EventSink {
} }
private void enqueue(Object event) { private void enqueue(Object event) {
if (isEnd) return; if (isEnd) {
return;
}
eventQueue.offer(event); eventQueue.offer(event);
} }
private void consume() { private void consume() {
if (eventSink == null) return; if (eventSink == null) {
while (!eventQueue.isEmpty()){ return;
}
while (!eventQueue.isEmpty()) {
Object event = eventQueue.poll(); Object event = eventQueue.poll();
if (event instanceof EndEvent) { if (event instanceof EndEvent) {
eventSink.endOfStream(); eventSink.endOfStream();
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import android.text.TextUtils; import android.text.TextUtils;
...@@ -14,6 +15,9 @@ import java.util.Map; ...@@ -14,6 +15,9 @@ import java.util.Map;
*/ */
public class FTXTransformation { public class FTXTransformation {
/**
* 将map转换为config
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static TXVodPlayConfig transformToVodConfig(Map<Object, Object> config) { public static TXVodPlayConfig transformToVodConfig(Map<Object, Object> config) {
TXVodPlayConfig playConfig = new TXVodPlayConfig(); TXVodPlayConfig playConfig = new TXVodPlayConfig();
...@@ -30,7 +34,7 @@ public class FTXTransformation { ...@@ -30,7 +34,7 @@ public class FTXTransformation {
playConfig.setTimeout(timeout); playConfig.setTimeout(timeout);
} }
Integer playerType = (Integer) config.get("playerType"); Integer playerType = (Integer) config.get("playerType");
if(null != playerType) { if (null != playerType) {
playConfig.setPlayerType(playerType); playConfig.setPlayerType(playerType);
} }
Map<String, String> headers = (Map<String, String>) config.get("headers"); Map<String, String> headers = (Map<String, String>) config.get("headers");
...@@ -39,15 +43,15 @@ public class FTXTransformation { ...@@ -39,15 +43,15 @@ public class FTXTransformation {
} }
playConfig.setHeaders(headers); playConfig.setHeaders(headers);
Boolean enableAccurateSeek = (Boolean) config.get("enableAccurateSeek"); Boolean enableAccurateSeek = (Boolean) config.get("enableAccurateSeek");
if(null != enableAccurateSeek) { if (null != enableAccurateSeek) {
playConfig.setEnableAccurateSeek(enableAccurateSeek); playConfig.setEnableAccurateSeek(enableAccurateSeek);
} }
Boolean autoRotate = (Boolean) config.get("autoRotate"); Boolean autoRotate = (Boolean) config.get("autoRotate");
if(null != autoRotate) { if (null != autoRotate) {
playConfig.setAutoRotate(autoRotate); playConfig.setAutoRotate(autoRotate);
} }
Boolean smoothSwitchBitrate = (Boolean) config.get("smoothSwitchBitrate"); Boolean smoothSwitchBitrate = (Boolean) config.get("smoothSwitchBitrate");
if(null != smoothSwitchBitrate) { if (null != smoothSwitchBitrate) {
playConfig.setSmoothSwitchBitrate(smoothSwitchBitrate); playConfig.setSmoothSwitchBitrate(smoothSwitchBitrate);
} }
String cacheMp4ExtName = (String) config.get("cacheMp4ExtName"); String cacheMp4ExtName = (String) config.get("cacheMp4ExtName");
...@@ -67,11 +71,11 @@ public class FTXTransformation { ...@@ -67,11 +71,11 @@ public class FTXTransformation {
playConfig.setMaxPreloadSize(maxPreloadSize); playConfig.setMaxPreloadSize(maxPreloadSize);
} }
Integer firstStartPlayBufferTime = (Integer) config.get("firstStartPlayBufferTime"); Integer firstStartPlayBufferTime = (Integer) config.get("firstStartPlayBufferTime");
if(null != firstStartPlayBufferTime) { if (null != firstStartPlayBufferTime) {
playConfig.setFirstStartPlayBufferTime(firstStartPlayBufferTime); playConfig.setFirstStartPlayBufferTime(firstStartPlayBufferTime);
} }
Integer nextStartPlayBufferTime = (Integer) config.get("nextStartPlayBufferTime"); Integer nextStartPlayBufferTime = (Integer) config.get("nextStartPlayBufferTime");
if(null != nextStartPlayBufferTime) { if (null != nextStartPlayBufferTime) {
playConfig.setNextStartPlayBufferTime(nextStartPlayBufferTime); playConfig.setNextStartPlayBufferTime(nextStartPlayBufferTime);
} }
...@@ -89,7 +93,7 @@ public class FTXTransformation { ...@@ -89,7 +93,7 @@ public class FTXTransformation {
} }
playConfig.setExtInfo(extInfoMap); playConfig.setExtInfo(extInfoMap);
Boolean enableRenderProcess = (Boolean) config.get("enableRenderProcess"); Boolean enableRenderProcess = (Boolean) config.get("enableRenderProcess");
if(null != enableRenderProcess) { if (null != enableRenderProcess) {
playConfig.setEnableRenderProcess(enableRenderProcess); playConfig.setEnableRenderProcess(enableRenderProcess);
} }
String preferredResolutionStr = (String) config.get("preferredResolution"); String preferredResolutionStr = (String) config.get("preferredResolution");
...@@ -101,50 +105,53 @@ public class FTXTransformation { ...@@ -101,50 +105,53 @@ public class FTXTransformation {
return playConfig; return playConfig;
} }
/**
* map转config
*/
public static TXLivePlayConfig transformToLiveConfig(Map<Object, Object> config) { public static TXLivePlayConfig transformToLiveConfig(Map<Object, Object> config) {
TXLivePlayConfig livePlayConfig = new TXLivePlayConfig(); TXLivePlayConfig livePlayConfig = new TXLivePlayConfig();
Double cacheTime = (Double) config.get("cacheTime"); Double cacheTime = (Double) config.get("cacheTime");
if(doubleIsNotEmpty(cacheTime)) { if (doubleIsNotEmpty(cacheTime)) {
livePlayConfig.setCacheTime(cacheTime.floatValue()); livePlayConfig.setCacheTime(cacheTime.floatValue());
} }
Double maxAutoAdjustCacheTime = (Double) config.get("maxAutoAdjustCacheTime"); Double maxAutoAdjustCacheTime = (Double) config.get("maxAutoAdjustCacheTime");
if(doubleIsNotEmpty(maxAutoAdjustCacheTime)) { if (doubleIsNotEmpty(maxAutoAdjustCacheTime)) {
livePlayConfig.setMaxAutoAdjustCacheTime(maxAutoAdjustCacheTime.floatValue()); livePlayConfig.setMaxAutoAdjustCacheTime(maxAutoAdjustCacheTime.floatValue());
} }
Double minAutoAdjustCacheTime = (Double) config.get("minAutoAdjustCacheTime"); Double minAutoAdjustCacheTime = (Double) config.get("minAutoAdjustCacheTime");
if(doubleIsNotEmpty(minAutoAdjustCacheTime)) { if (doubleIsNotEmpty(minAutoAdjustCacheTime)) {
livePlayConfig.setMinAutoAdjustCacheTime(minAutoAdjustCacheTime.floatValue()); livePlayConfig.setMinAutoAdjustCacheTime(minAutoAdjustCacheTime.floatValue());
} }
Integer videoBlockThreshold = (Integer) config.get("videoBlockThreshold"); Integer videoBlockThreshold = (Integer) config.get("videoBlockThreshold");
if(intIsNotEmpty(videoBlockThreshold)) { if (intIsNotEmpty(videoBlockThreshold)) {
livePlayConfig.setVideoBlockThreshold(videoBlockThreshold); livePlayConfig.setVideoBlockThreshold(videoBlockThreshold);
} }
Integer connectRetryCount = (Integer) config.get("connectRetryCount"); Integer connectRetryCount = (Integer) config.get("connectRetryCount");
if(intIsNotEmpty(connectRetryCount)) { if (intIsNotEmpty(connectRetryCount)) {
livePlayConfig.setConnectRetryCount(connectRetryCount); livePlayConfig.setConnectRetryCount(connectRetryCount);
} }
Integer connectRetryInterval = (Integer) config.get("connectRetryInterval"); Integer connectRetryInterval = (Integer) config.get("connectRetryInterval");
if(intIsNotEmpty(connectRetryInterval)) { if (intIsNotEmpty(connectRetryInterval)) {
livePlayConfig.setConnectRetryInterval(connectRetryInterval); livePlayConfig.setConnectRetryInterval(connectRetryInterval);
} }
Boolean autoAdjustCacheTime = (Boolean) config.get("autoAdjustCacheTime"); Boolean autoAdjustCacheTime = (Boolean) config.get("autoAdjustCacheTime");
if(null != autoAdjustCacheTime) { if (null != autoAdjustCacheTime) {
livePlayConfig.setAutoAdjustCacheTime(autoAdjustCacheTime); livePlayConfig.setAutoAdjustCacheTime(autoAdjustCacheTime);
} }
Boolean enableAec= (Boolean) config.get("enableAec"); Boolean enableAec = (Boolean) config.get("enableAec");
if(null != enableAec) { if (null != enableAec) {
livePlayConfig.setEnableAEC(enableAec); livePlayConfig.setEnableAEC(enableAec);
} }
Boolean enableMessage = (Boolean) config.get("enableMessage"); Boolean enableMessage = (Boolean) config.get("enableMessage");
if(null != enableMessage) { if (null != enableMessage) {
livePlayConfig.setEnableMessage(enableMessage); livePlayConfig.setEnableMessage(enableMessage);
} }
Boolean enableMetaData = (Boolean) config.get("enableMetaData"); Boolean enableMetaData = (Boolean) config.get("enableMetaData");
if(null != enableMetaData) { if (null != enableMetaData) {
livePlayConfig.setEnableMetaData(enableMetaData); livePlayConfig.setEnableMetaData(enableMetaData);
} }
String flvSessionKey = (String) config.get("flvSessionKey"); String flvSessionKey = (String) config.get("flvSessionKey");
if(!TextUtils.isEmpty(flvSessionKey)) { if (!TextUtils.isEmpty(flvSessionKey)) {
livePlayConfig.setFlvSessionKey(flvSessionKey); livePlayConfig.setFlvSessionKey(flvSessionKey);
} }
return livePlayConfig; return livePlayConfig;
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import android.graphics.Bitmap; import android.graphics.Bitmap;
...@@ -35,15 +36,15 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -35,15 +36,15 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding; private FlutterPlugin.FlutterPluginBinding mFlutterPluginBinding;
final private MethodChannel mMethodChannel; private final MethodChannel mMethodChannel;
private final EventChannel mEventChannel; private final EventChannel mEventChannel;
private final EventChannel mNetChannel; private final EventChannel mNetChannel;
private SurfaceTexture mSurfaceTexture; private SurfaceTexture mSurfaceTexture;
private Surface mSurface; private Surface mSurface;
final private FTXPlayerEventSink mEventSink = new FTXPlayerEventSink(); private final FTXPlayerEventSink mEventSink = new FTXPlayerEventSink();
final private FTXPlayerEventSink mNetStatusSink = new FTXPlayerEventSink(); private final FTXPlayerEventSink mNetStatusSink = new FTXPlayerEventSink();
private TXVodPlayer mVodPlayer; private TXVodPlayer mVodPlayer;
private TXImageSprite mTxImageSprite; private TXImageSprite mTxImageSprite;
...@@ -67,12 +68,15 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -67,12 +68,15 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
seek(playTime); seek(playTime);
// 启动pip的时候,当前player已经暂停,pip退出之后,如果退出的时候pip还处于播放状态,那么当前player也置为播放状态 // 启动pip的时候,当前player已经暂停,pip退出之后,如果退出的时候pip还处于播放状态,那么当前player也置为播放状态
boolean isPipPlaying = result.isPlaying(); boolean isPipPlaying = result.isPlaying();
if(isPipPlaying) { if (isPipPlaying) {
resume(); resume();
} }
} }
}; };
/**
* 点播播放器
*/
public FTXVodPlayer(FlutterPlugin.FlutterPluginBinding flutterPluginBinding, FTXPIPManager pipManager) { public FTXVodPlayer(FlutterPlugin.FlutterPluginBinding flutterPluginBinding, FTXPIPManager pipManager) {
super(); super();
mPipManager = pipManager; mPipManager = pipManager;
...@@ -80,12 +84,12 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -80,12 +84,12 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
mVideoModel = new VideoModel(); mVideoModel = new VideoModel();
mVideoModel.setPlayerType(FTXEvent.PLAYER_VOD); mVideoModel.setPlayerType(FTXEvent.PLAYER_VOD);
mMethodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent" + mMethodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent"
".com/txvodplayer/" + super.getPlayerId()); + ".com/txvodplayer/" + super.getPlayerId());
mMethodChannel.setMethodCallHandler(this); mMethodChannel.setMethodCallHandler(this);
mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent" + mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent"
".com/txvodplayer/event/" + super.getPlayerId()); + ".com/txvodplayer/event/" + super.getPlayerId());
mEventChannel.setStreamHandler(new EventChannel.StreamHandler() { mEventChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override @Override
public void onListen(Object o, EventChannel.EventSink eventSink) { public void onListen(Object o, EventChannel.EventSink eventSink) {
...@@ -98,8 +102,8 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -98,8 +102,8 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
} }
}); });
mNetChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent" + mNetChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent"
".com/txvodplayer/net/" + super.getPlayerId()); + ".com/txvodplayer/net/" + super.getPlayerId());
mNetChannel.setStreamHandler(new EventChannel.StreamHandler() { mNetChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override @Override
public void onListen(Object o, EventChannel.EventSink eventSink) { public void onListen(Object o, EventChannel.EventSink eventSink) {
...@@ -147,9 +151,9 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -147,9 +151,9 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
@Override @Override
public void onPlayEvent(TXVodPlayer txVodPlayer, int event, Bundle bundle) { public void onPlayEvent(TXVodPlayer txVodPlayer, int event, Bundle bundle) {
if (event == TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION) { if (event == TXLiveConstants.PLAY_EVT_CHANGE_RESOLUTION) {
String EVT_PARAM3 = bundle.getString("EVT_PARAM3"); String evtParam3 = bundle.getString("EVT_PARAM3");
if (!TextUtils.isEmpty(EVT_PARAM3)) { if (!TextUtils.isEmpty(evtParam3)) {
String[] array = EVT_PARAM3.split(","); String[] array = evtParam3.split(",");
if (array.length == 6) { if (array.length == 6) {
int videoWidth = Integer.parseInt(array[4]) - Integer.parseInt(array[2]) + 1; int videoWidth = Integer.parseInt(array[4]) - Integer.parseInt(array[2]) + 1;
int videoHeight = Integer.parseInt(array[5]) - Integer.parseInt(array[3]) + 1; int videoHeight = Integer.parseInt(array[5]) - Integer.parseInt(array[3]) + 1;
...@@ -182,7 +186,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -182,7 +186,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
// surface 的大小默认是宽高为1,当硬解失败时或使用软解时,软解会依赖surface的窗口渲染,不更新会导致只有1px的内容 // surface 的大小默认是宽高为1,当硬解失败时或使用软解时,软解会依赖surface的窗口渲染,不更新会导致只有1px的内容
private void setDefaultBufferSizeForSoftDecode(int width, int height) { private void setDefaultBufferSizeForSoftDecode(int width, int height) {
if (mSurfaceTextureEntry!= null && mSurfaceTextureEntry.surfaceTexture() != null) { if (mSurfaceTextureEntry != null && mSurfaceTextureEntry.surfaceTexture() != null) {
SurfaceTexture surfaceTexture = mSurfaceTextureEntry.surfaceTexture(); SurfaceTexture surfaceTexture = mSurfaceTextureEntry.surfaceTexture();
surfaceTexture.setDefaultBufferSize(width, height); surfaceTexture.setDefaultBufferSize(width, height);
if (mSurface != null) { if (mSurface != null) {
...@@ -341,26 +345,26 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -341,26 +345,26 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
mPipParams.setCurrentPlayTime(getCurrentPlaybackTime()); mPipParams.setCurrentPlayTime(getCurrentPlaybackTime());
int pipResult = mPipManager.enterPip(mPipParams, mVideoModel); int pipResult = mPipManager.enterPip(mPipParams, mVideoModel);
// 启动成功之后,暂停当前界面视频 // 启动成功之后,暂停当前界面视频
if(pipResult == FTXEvent.NO_ERROR) { if (pipResult == FTXEvent.NO_ERROR) {
pause(); pause();
} }
result.success(pipResult); result.success(pipResult);
} else if(call.method.equals("exitPictureInPictureMode")) { } else if (call.method.equals("exitPictureInPictureMode")) {
mPipManager.exitPip(); mPipManager.exitPip();
result.success(null); result.success(null);
} else if(call.method.equals("initImageSprite")) { } else if (call.method.equals("initImageSprite")) {
String vvtUrl = call.argument("vvtUrl"); String vvtUrl = call.argument("vvtUrl");
List<String> imageUrls = call.argument("imageUrls"); List<String> imageUrls = call.argument("imageUrls");
mTxImageSprite.setVTTUrlAndImageUrls(vvtUrl,imageUrls); mTxImageSprite.setVTTUrlAndImageUrls(vvtUrl,imageUrls);
result.success(null); result.success(null);
} else if(call.method.equals("getImageSprite")) { } else if (call.method.equals("getImageSprite")) {
final Double time = call.argument("time"); final Double time = call.argument("time");
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
Bitmap bitmap = mTxImageSprite.getThumbnail(time.floatValue()); Bitmap bitmap = mTxImageSprite.getThumbnail(time.floatValue());
ByteArrayOutputStream stream = new ByteArrayOutputStream(); ByteArrayOutputStream stream = new ByteArrayOutputStream();
if(null != bitmap) { if (null != bitmap) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray(); byte[] byteArray = stream.toByteArray();
result.success(byteArray); result.success(byteArray);
...@@ -398,11 +402,11 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -398,11 +402,11 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
} }
int startVodPlay(String url) { int startVodPlay(String url) {
mVideoModel.setVideoUrl(url);
mVideoModel.setAppId(0);
mVideoModel.setFileId("");
mVideoModel.setPSign("");
if (mVodPlayer != null) { if (mVodPlayer != null) {
mVideoModel.setVideoUrl(url);
mVideoModel.setAppId(0);
mVideoModel.setFileId("");
mVideoModel.setPSign("");
return mVodPlayer.startVodPlay(url); return mVodPlayer.startVodPlay(url);
} }
return Uninitialized; return Uninitialized;
...@@ -573,8 +577,10 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC ...@@ -573,8 +577,10 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
if (mVodPlayer != null) { if (mVodPlayer != null) {
if (TextUtils.isEmpty(token)) { if (TextUtils.isEmpty(token)) {
mVodPlayer.setToken(null); mVodPlayer.setToken(null);
mVideoModel.setToken(null);
} else { } else {
mVodPlayer.setToken(token); mVodPlayer.setToken(token);
mVideoModel.setToken(token);
} }
} }
} }
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter; package com.tencent.vod.flutter;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
...@@ -40,6 +41,7 @@ import io.flutter.plugin.common.MethodChannel.Result; ...@@ -40,6 +41,7 @@ import io.flutter.plugin.common.MethodChannel.Result;
* The MethodChannel that will the communication between Flutter and native Android * The MethodChannel that will the communication between Flutter and native Android
* This local reference serves to register the plugin with the Flutter Engine and unregister it * This local reference serves to register the plugin with the Flutter Engine and unregister it
* when the Flutter Engine is detached from the Activity * when the Flutter Engine is detached from the Activity
* </p>
*/ */
public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware { public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
...@@ -84,7 +86,8 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti ...@@ -84,7 +86,8 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
channel.setMethodCallHandler(this); channel.setMethodCallHandler(this);
mPlayers = new SparseArray(); mPlayers = new SparseArray();
initAudioManagerIfNeed(); initAudioManagerIfNeed();
mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent.com/playerPlugin/event"); mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
"cloud.tencent.com/playerPlugin/event");
mEventChannel.setStreamHandler(new EventChannel.StreamHandler() { mEventChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override @Override
public void onListen(Object o, EventChannel.EventSink eventSink) { public void onListen(Object o, EventChannel.EventSink eventSink) {
...@@ -109,7 +112,8 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti ...@@ -109,7 +112,8 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
mPlayers.append(playerId, player); mPlayers.append(playerId, player);
result.success(playerId); result.success(playerId);
} else if (call.method.equals("createLivePlayer")) { } else if (call.method.equals("createLivePlayer")) {
FTXLivePlayer player = new FTXLivePlayer(mFlutterPluginBinding, mActivityPluginBinding.getActivity(), mTxPipManager); FTXLivePlayer player = new FTXLivePlayer(mFlutterPluginBinding, mActivityPluginBinding.getActivity(),
mTxPipManager);
int playerId = player.getPlayerId(); int playerId = player.getPlayerId();
mPlayers.append(playerId, player); mPlayers.append(playerId, player);
result.success(playerId); result.success(playerId);
...@@ -186,11 +190,11 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti ...@@ -186,11 +190,11 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
result.success(mTxPipManager.isSupportDevice()); result.success(mTxPipManager.isSupportDevice());
} else if (call.method.equals("getLiteAVSDKVersion")) { } else if (call.method.equals("getLiteAVSDKVersion")) {
result.success(TXLiveBase.getSDKVersionStr()); result.success(TXLiveBase.getSDKVersionStr());
} else if(call.method.equals("setGlobalEnv")) { } else if (call.method.equals("setGlobalEnv")) {
String envConfig = call.argument("envConfig"); String envConfig = call.argument("envConfig");
int setResult = TXLiveBase.setGlobalEnv(envConfig); int setResult = TXLiveBase.setGlobalEnv(envConfig);
result.success(setResult); result.success(setResult);
} else if(call.method.equals("startVideoOrientationService")) { } else if (call.method.equals("startVideoOrientationService")) {
boolean setResult = startVideoOrientationService(); boolean setResult = startVideoOrientationService();
result.success(setResult); result.success(setResult);
} else { } else {
...@@ -199,11 +203,11 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti ...@@ -199,11 +203,11 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
} }
private boolean startVideoOrientationService() { private boolean startVideoOrientationService() {
if(null == mFlutterPluginBinding) { if (null == mFlutterPluginBinding) {
return false; return false;
} }
if(null == mOrientationManager) { if (null == mOrientationManager) {
try{ try {
mOrientationManager = new OrientationEventListener(mFlutterPluginBinding.getApplicationContext()) { mOrientationManager = new OrientationEventListener(mFlutterPluginBinding.getApplicationContext()) {
@Override @Override
public void onOrientationChanged(int orientation) { public void onOrientationChanged(int orientation) {
...@@ -300,7 +304,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti ...@@ -300,7 +304,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
*/ */
protected boolean isAutoRotateOn() { protected boolean isAutoRotateOn() {
//获取系统是否允许自动旋转屏幕 //获取系统是否允许自动旋转屏幕
try{ try {
return (android.provider.Settings.System.getInt( return (android.provider.Settings.System.getInt(
mFlutterPluginBinding.getApplicationContext().getContentResolver(), mFlutterPluginBinding.getApplicationContext().getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 0) == 1); Settings.System.ACCELEROMETER_ROTATION, 0) == 1);
......
...@@ -18,6 +18,7 @@ public class VideoModel implements Parcelable { ...@@ -18,6 +18,7 @@ public class VideoModel implements Parcelable {
private String pSign; private String pSign;
private int mPlayerType = FTXEvent.PLAYER_VOD; private int mPlayerType = FTXEvent.PLAYER_VOD;
private int mLiveType = TXLivePlayer.PLAY_TYPE_LIVE_FLV; private int mLiveType = TXLivePlayer.PLAY_TYPE_LIVE_FLV;
private String mToken;
public VideoModel() {} public VideoModel() {}
...@@ -28,6 +29,7 @@ public class VideoModel implements Parcelable { ...@@ -28,6 +29,7 @@ public class VideoModel implements Parcelable {
pSign = in.readString(); pSign = in.readString();
mPlayerType = in.readInt(); mPlayerType = in.readInt();
mLiveType = in.readInt(); mLiveType = in.readInt();
mToken = in.readString();
} }
public static final Creator<VideoModel> CREATOR = new Creator<VideoModel>() { public static final Creator<VideoModel> CREATOR = new Creator<VideoModel>() {
...@@ -50,6 +52,14 @@ public class VideoModel implements Parcelable { ...@@ -50,6 +52,14 @@ public class VideoModel implements Parcelable {
this.videoUrl = videoUrl; this.videoUrl = videoUrl;
} }
public String getToken() {
return mToken;
}
public void setToken(String token) {
this.mToken = token;
}
public int getAppId() { public int getAppId() {
return appId; return appId;
} }
...@@ -103,5 +113,6 @@ public class VideoModel implements Parcelable { ...@@ -103,5 +113,6 @@ public class VideoModel implements Parcelable {
dest.writeString(pSign); dest.writeString(pSign);
dest.writeInt(mPlayerType); dest.writeInt(mPlayerType);
dest.writeInt(mLiveType); dest.writeInt(mLiveType);
dest.writeString(mToken);
} }
} }
...@@ -79,6 +79,9 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -79,6 +79,9 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
case FTXEvent.EXTRA_PIP_PLAY_FORWARD: case FTXEvent.EXTRA_PIP_PLAY_FORWARD:
handlePlayForward(); handlePlayForward();
break; break;
default:
Log.e(TAG, "unknown control code");
break;
} }
} }
} }
...@@ -88,7 +91,6 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -88,7 +91,6 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
registerPipBroadcast();
Intent intent = getIntent(); Intent intent = getIntent();
PipParams params = intent.getParcelableExtra(FTXEvent.EXTRA_NAME_PARAMS); PipParams params = intent.getParcelableExtra(FTXEvent.EXTRA_NAME_PARAMS);
if (null == params) { if (null == params) {
...@@ -102,6 +104,7 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -102,6 +104,7 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
configPipMode(null); configPipMode(null);
} }
} }
registerPipBroadcast();
handleIntent(intent); handleIntent(intent);
setContentView(R.layout.activity_flutter_pip_impl); setContentView(R.layout.activity_flutter_pip_impl);
mVodPlayer = new TXVodPlayer(this); mVodPlayer = new TXVodPlayer(this);
...@@ -161,6 +164,11 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -161,6 +164,11 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
super.onPictureInPictureModeChanged(isInPictureInPictureMode); super.onPictureInPictureModeChanged(isInPictureInPictureMode);
} }
@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
}
@Override @Override
public void onPictureInPictureUiStateChanged(@NonNull PictureInPictureUiState pipState) { public void onPictureInPictureUiStateChanged(@NonNull PictureInPictureUiState pipState) {
super.onPictureInPictureUiStateChanged(pipState); super.onPictureInPictureUiStateChanged(pipState);
...@@ -274,6 +282,7 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -274,6 +282,7 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
if (mVideoModel.getPlayerType() == FTXEvent.PLAYER_VOD) { if (mVideoModel.getPlayerType() == FTXEvent.PLAYER_VOD) {
mVodPlayer.setStartTime(playTime); mVodPlayer.setStartTime(playTime);
mVodPlayer.setAutoPlay(isPlaying); mVodPlayer.setAutoPlay(isPlaying);
mVodPlayer.setToken(mVideoModel.getToken());
if (!TextUtils.isEmpty(mVideoModel.getVideoUrl())) { if (!TextUtils.isEmpty(mVideoModel.getVideoUrl())) {
mVodPlayer.startVodPlay(mVideoModel.getVideoUrl()); mVodPlayer.startVodPlay(mVideoModel.getVideoUrl());
} else if (!TextUtils.isEmpty(mVideoModel.getFileId())) { } else if (!TextUtils.isEmpty(mVideoModel.getFileId())) {
...@@ -293,11 +302,6 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -293,11 +302,6 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
} }
} }
@Override
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
}
@Override @Override
public void surfaceCreated(SurfaceHolder holder) { public void surfaceCreated(SurfaceHolder holder) {
mIsSurfaceCreated = true; mIsSurfaceCreated = true;
...@@ -319,7 +323,6 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -319,7 +323,6 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
unRegisterPipBroadcast();
mVodPlayer.stopPlay(true); mVodPlayer.stopPlay(true);
mLivePlayer.stopPlay(true); mLivePlayer.stopPlay(true);
mIsNeedToStop = true; mIsNeedToStop = true;
...@@ -333,6 +336,7 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -333,6 +336,7 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
@Override @Override
protected void onDestroy() { protected void onDestroy() {
unRegisterPipBroadcast();
super.onDestroy(); super.onDestroy();
} }
...@@ -413,22 +417,22 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -413,22 +417,22 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
@Override @Override
public void onPlayEvent(TXVodPlayer txVodPlayer, int event, Bundle bundle) { public void onPlayEvent(TXVodPlayer txVodPlayer, int event, Bundle bundle) {
if (VERSION.SDK_INT >= VERSION_CODES.N && isInPictureInPictureMode()) { if (VERSION.SDK_INT >= VERSION_CODES.N && isInPictureInPictureMode()) {
if(null != mCurrentParams) { if (null != mCurrentParams) {
if (event == TXLiveConstants.PLAY_EVT_PLAY_END) { if (event == TXLiveConstants.PLAY_EVT_PLAY_END) {
// 播放完毕的时候,自动将播放按钮置为播放 // 播放完毕的时候,自动将播放按钮置为播放
mCurrentParams.setIsPlaying(false); mCurrentParams.setIsPlaying(false);
} else if(event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) { } else if (event == TXLiveConstants.PLAY_EVT_PLAY_BEGIN) {
// 播放开始的时候,自动将播放按钮置为暂停 // 播放开始的时候,自动将播放按钮置为暂停
mCurrentParams.setIsPlaying(true); mCurrentParams.setIsPlaying(true);
} }
updatePip(mCurrentParams); updatePip(mCurrentParams);
} }
if(event == TXLiveConstants.PLAY_EVT_PLAY_PROGRESS) { if (event == TXLiveConstants.PLAY_EVT_PLAY_PROGRESS) {
int progress = bundle.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS); int progress = bundle.getInt(TXLiveConstants.EVT_PLAY_PROGRESS_MS);
int duration = bundle.getInt(TXLiveConstants.EVT_PLAY_DURATION_MS); int duration = bundle.getInt(TXLiveConstants.EVT_PLAY_DURATION_MS);
float percentage = (progress / 1000F) / (duration / 1000F); float percentage = (progress / 1000F) / (duration / 1000F);
final int progressToShow = Math.round(percentage * mVideoProgress.getMax()); final int progressToShow = Math.round(percentage * mVideoProgress.getMax());
if(null != mVideoProgress) { if (null != mVideoProgress) {
mVideoProgress.post(new Runnable() { mVideoProgress.post(new Runnable() {
@Override @Override
public void run() { public void run() {
...@@ -441,11 +445,11 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback, ...@@ -441,11 +445,11 @@ public class FlutterPipImplActivity extends FlutterActivity implements Callback,
} }
@Override @Override
public void onNetStatus(TXVodPlayer txVodPlayer, Bundle bundle) { public void onPlayEvent(int event, Bundle bundle) {
} }
@Override @Override
public void onPlayEvent(int event, Bundle bundle) { public void onNetStatus(TXVodPlayer txVodPlayer, Bundle bundle) {
} }
@Override @Override
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.super_player_example"> package="com.example.player">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.example.super_player_example"> package="com.example.player">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
tools:replace="android:label"> tools:replace="android:label">
<activity <activity
android:name=".MainActivity" android:name="com.example.player.MainActivity"
android:supportsPictureInPicture="true" android:supportsPictureInPicture="true"
android:resizeableActivity="true" android:resizeableActivity="true"
android:launchMode="singleTask" android:launchMode="singleTask"
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
package com.example.super_player_example;
package com.example.player;
import io.flutter.embedding.android.FlutterActivity; import io.flutter.embedding.android.FlutterActivity;
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.super_player_example"> package="com.example.player">
<!-- Flutter needs it to communicate with the running application <!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc. to allow setting breakpoints, to provide hot reload, etc.
--> -->
......
// Copyright (c) 2022 Tencent. All rights reserved.
#import <Flutter/Flutter.h> #import <Flutter/Flutter.h>
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
......
// Copyright (c) 2022 Tencent. All rights reserved.
#import "AppDelegate.h" #import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h" #import "GeneratedPluginRegistrant.h"
......
...@@ -26,6 +26,7 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -26,6 +26,7 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
List<SuperPlayerModel> videoModels = []; List<SuperPlayerModel> videoModels = [];
bool _isFullScreen = false; bool _isFullScreen = false;
late SuperPlayerController _controller; late SuperPlayerController _controller;
SuperVodDataLoader loader = SuperVodDataLoader();
StreamSubscription? simpleEventSubscription; StreamSubscription? simpleEventSubscription;
int tabSelectPos = 0; int tabSelectPos = 0;
SuperPlayerModel? currentVideoModel; SuperPlayerModel? currentVideoModel;
...@@ -212,7 +213,12 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -212,7 +213,12 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
return; return;
} }
playCurrentModel(model, 0); loader.getVideoData(model, (resultModel) {
setState(() {
videoModels.add(resultModel);
});
playCurrentModel(resultModel, 0);
});
}, },
needPisgn: !isLive, needPisgn: !isLive,
showFileEdited: !isLive, showFileEdited: !isLive,
...@@ -327,7 +333,6 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -327,7 +333,6 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
models.add(model); models.add(model);
List<Future<void>> requestList = []; List<Future<void>> requestList = [];
SuperVodDataLoader loader = SuperVodDataLoader();
for (SuperPlayerModel tempModel in models) { for (SuperPlayerModel tempModel in models) {
requestList.add(loader.getVideoData(tempModel, (_) {})); requestList.add(loader.getVideoData(tempModel, (_) {}));
} }
......
...@@ -23,6 +23,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO ...@@ -23,6 +23,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
String _url = String _url =
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo1080p.flv"; "http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo1080p.flv";
bool _isStop = true; bool _isStop = true;
bool _isPlaying = false;
double _maxLiveProgressTime = 0; double _maxLiveProgressTime = 0;
StreamSubscription? playEventSubscription; StreamSubscription? playEventSubscription;
StreamSubscription? playNetEventSubscription; StreamSubscription? playNetEventSubscription;
...@@ -45,6 +46,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO ...@@ -45,6 +46,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
event["event"] == TXVodPlayEvent.PLAY_EVT_RCV_FIRST_I_FRAME) { event["event"] == TXVodPlayEvent.PLAY_EVT_RCV_FIRST_I_FRAME) {
//首帧出现 //首帧出现
_isStop = false; _isStop = false;
_isPlaying = true;
EasyLoading.dismiss(); EasyLoading.dismiss();
} else if (event["event"] == TXVodPlayEvent.PLAY_EVT_STREAM_SWITCH_SUCC) { } else if (event["event"] == TXVodPlayEvent.PLAY_EVT_STREAM_SWITCH_SUCC) {
//切换流成功 //切换流成功
...@@ -102,7 +104,9 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO ...@@ -102,7 +104,9 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
case AppLifecycleState.inactive: case AppLifecycleState.inactive:
break; break;
case AppLifecycleState.resumed: case AppLifecycleState.resumed:
_controller.resume(); if(_isPlaying) {
_controller.resume();
}
break; break;
case AppLifecycleState.paused: case AppLifecycleState.paused:
_controller.pause(); _controller.pause();
...@@ -181,6 +185,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO ...@@ -181,6 +185,7 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
EasyLoading.showError('已经停止播放, 请重新播放'); EasyLoading.showError('已经停止播放, 请重新播放');
return; return;
} }
_isPlaying = false;
_controller.pause(); _controller.pause();
}, },
child: Container( child: Container(
......
...@@ -30,6 +30,7 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer> ...@@ -30,6 +30,7 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer>
double _rate = 1.0; double _rate = 1.0;
bool enableHardware = true; bool enableHardware = true;
int volume = 80; int volume = 80;
bool _isPlaying = false;
StreamSubscription? playEventSubscription; StreamSubscription? playEventSubscription;
StreamSubscription? playNetEventSubscription; StreamSubscription? playNetEventSubscription;
...@@ -52,6 +53,7 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer> ...@@ -52,6 +53,7 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer>
event["event"] == TXVodPlayEvent.PLAY_EVT_RCV_FIRST_I_FRAME) { event["event"] == TXVodPlayEvent.PLAY_EVT_RCV_FIRST_I_FRAME) {
EasyLoading.dismiss(); EasyLoading.dismiss();
_supportedBitrates = (await _controller.getSupportedBitrates())!; _supportedBitrates = (await _controller.getSupportedBitrates())!;
_isPlaying = true;
} else if (event["event"] == TXVodPlayEvent.PLAY_EVT_PLAY_PROGRESS) { } else if (event["event"] == TXVodPlayEvent.PLAY_EVT_PLAY_PROGRESS) {
_currentProgress = event[TXVodPlayEvent.EVT_PLAY_PROGRESS].toDouble(); _currentProgress = event[TXVodPlayEvent.EVT_PLAY_PROGRESS].toDouble();
double videoDuration = event[TXVodPlayEvent.EVT_PLAY_DURATION].toDouble(); // 总播放时长,转换后的单位 秒 double videoDuration = event[TXVodPlayEvent.EVT_PLAY_DURATION].toDouble(); // 总播放时长,转换后的单位 秒
...@@ -103,7 +105,9 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer> ...@@ -103,7 +105,9 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer>
case AppLifecycleState.inactive: case AppLifecycleState.inactive:
break; break;
case AppLifecycleState.resumed: case AppLifecycleState.resumed:
_controller.resume(); if(_isPlaying) {
_controller.resume();
}
break; break;
case AppLifecycleState.paused: case AppLifecycleState.paused:
_controller.pause(); _controller.pause();
...@@ -187,7 +191,9 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer> ...@@ -187,7 +191,9 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer>
), ),
), ),
new GestureDetector( new GestureDetector(
onTap: () => {_controller.pause()}, onTap: () {
_isPlaying = false;
_controller.pause();},
child: Container( child: Container(
alignment: Alignment.center, alignment: Alignment.center,
child: Text( child: Text(
......
...@@ -125,7 +125,7 @@ class _DemoInputDialogState extends State<DemoInputDialog> { ...@@ -125,7 +125,7 @@ class _DemoInputDialogState extends State<DemoInputDialog> {
decoration: InputDecoration( decoration: InputDecoration(
enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Colors.green.withOpacity(0.4), width: 3.0)), enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Colors.green.withOpacity(0.4), width: 3.0)),
focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Colors.green, width: 4.0)), focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(10.0)), borderSide: BorderSide(color: Colors.green, width: 4.0)),
labelText:"请输入fileId", labelStyle: TextStyle(color: Colors.grey), labelText:"请输入fileid", labelStyle: TextStyle(color: Colors.grey),
suffixIcon: IconButton( suffixIcon: IconButton(
icon: Icon(Icons.close), icon: Icon(Icons.close),
onPressed: () { onPressed: () {
......
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
#import "FTXEvent.h" #import "FTXEvent.h"
@interface CommonUtil : NSObject @interface CommonUtil : NSObject
+(int)getCacheVideoQuality:(int)width height:(int)pHeight;
+(int)getDownloadEventByState:(int)downloadState; +(NSNumber*)getCacheVideoQuality:(int)width height:(int)pHeight;
+(NSNumber*)getDownloadEventByState:(int)downloadState;
@end @end
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
@implementation CommonUtil @implementation CommonUtil
+ (int)getCacheVideoQuality:(int)width height:(int)pHeight{ + (NSNumber*)getCacheVideoQuality:(int)width height:(int)pHeight{
int minValue = MIN(width, pHeight); int minValue = MIN(width, pHeight);
int cacheQualityIndex; int cacheQualityIndex;
if (minValue == 240 || minValue == 180) { if (minValue == 240 || minValue == 180) {
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
} else { } else {
cacheQualityIndex = TXVodQualityFLU; cacheQualityIndex = TXVodQualityFLU;
} }
return cacheQualityIndex; return [NSNumber numberWithInt:cacheQualityIndex];
} }
+ (int)getDownloadEventByState:(int)downloadState{ + (NSNumber*)getDownloadEventByState:(int)downloadState{
int result; int result;
switch (downloadState) { switch (downloadState) {
case TXVodDownloadMediaInfoStateInit: case TXVodDownloadMediaInfoStateInit:
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
result = EVENT_DOWNLOAD_ERROR; result = EVENT_DOWNLOAD_ERROR;
break; break;
} }
return result; return [NSNumber numberWithInt:result];;
} }
......
...@@ -6,9 +6,9 @@ ...@@ -6,9 +6,9 @@
@interface FTXAudioManager : NSObject @interface FTXAudioManager : NSObject
- (float)getVolume; - (CGFloat)getVolume;
- (void)setVolume:(float)value; - (void)setVolume:(CGFloat)value;
- (void)setVolumeUIVisible:(BOOL)volumeUIVisible; - (void)setVolumeUIVisible:(BOOL)volumeUIVisible;
......
...@@ -34,13 +34,13 @@ NSString *const NOTIFCATION_NAME = @"SystemVolumeDidChange"; ...@@ -34,13 +34,13 @@ NSString *const NOTIFCATION_NAME = @"SystemVolumeDidChange";
return self; return self;
}; };
- (float)getVolume - (CGFloat)getVolume
{ {
return _volumeSlider.value > 0 ? _volumeSlider.value : [[AVAudioSession sharedInstance]outputVolume]; return _volumeSlider.value > 0 ? _volumeSlider.value : [[AVAudioSession sharedInstance]outputVolume];
} }
- (void)setVolume:(float)value - (void)setVolume:(CGFloat)value
{ {
// 需要设置 showsVolumeSlider 为 YES // 需要设置 showsVolumeSlider 为 YES
volumeView.showsVolumeSlider = YES; volumeView.showsVolumeSlider = YES;
......
...@@ -211,7 +211,7 @@ ...@@ -211,7 +211,7 @@
if(nil != info && [NSNull null] != (NSNull *)info) { if(nil != info && [NSNull null] != (NSNull *)info) {
[dict setValue:info.playPath forKey:@"playPath"]; [dict setValue:info.playPath forKey:@"playPath"];
[dict setValue:@(info.progress) forKey:@"progress"]; [dict setValue:@(info.progress) forKey:@"progress"];
[dict setValue:@([CommonUtil getDownloadEventByState:(int)info.downloadState]) forKey:@"downloadState"]; [dict setValue:[CommonUtil getDownloadEventByState:(int)info.downloadState] forKey:@"downloadState"];
[dict setValue:info.userName forKey:@"userName"]; [dict setValue:info.userName forKey:@"userName"];
[dict setValue:@(info.duration) forKey:@"duration"]; [dict setValue:@(info.duration) forKey:@"duration"];
[dict setValue:@(info.playableDuration) forKey:@"playableDuration"]; [dict setValue:@(info.playableDuration) forKey:@"playableDuration"];
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
#ifndef FTXEvent_h #ifndef SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXEVENT_H_
#define FTXEvent_h #define SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXEVENT_H_
// 音频变化事件code // 音频变化事件code
#define EVENT_VOLUME_CHANGED 1 #define EVENT_VOLUME_CHANGED 1
...@@ -59,4 +59,4 @@ ...@@ -59,4 +59,4 @@
// 横屏,底部在左 // 横屏,底部在左
#define ORIENTATION_LANDSCAPE_LEFT 414 #define ORIENTATION_LANDSCAPE_LEFT 414
#endif /* FTXEvent_h */ #endif // SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXEVENT_H_
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
#ifndef SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXLIVEPLAYER_H_
#define SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXLIVEPLAYER_H_
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "FTXBasePlayer.h" #import "FTXBasePlayer.h"
...@@ -14,3 +16,5 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -14,3 +16,5 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
#endif // SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXLIVEPLAYER_H_
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
#ifndef SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXPLAYEREVENTSINKQUEUE_H_
#define SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXPLAYEREVENTSINKQUEUE_H_
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <Flutter/Flutter.h> #import <Flutter/Flutter.h>
...@@ -7,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -7,7 +9,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface FTXPlayerEventSinkQueue : NSObject @interface FTXPlayerEventSinkQueue : NSObject
- (void)success:(NSObject *)event; - (void)success:(id)event;
- (void)setDelegate:(_Nullable FlutterEventSink)sink; - (void)setDelegate:(_Nullable FlutterEventSink)sink;
- (void)error:(NSString *)code - (void)error:(NSString *)code
...@@ -17,3 +19,4 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -17,3 +19,4 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
#endif // SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXPLAYEREVENTSINKQUEUE_H_
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#pragma mark - public #pragma mark - public
- (void)success:(NSObject *)event - (void)success:(id)event
{ {
[self enqueue:event]; [self enqueue:event];
[self flushIfNeed]; [self flushIfNeed];
......
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
#ifndef SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXTRANSFORMATION_H_
#define SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXTRANSFORMATION_H_
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <TXLiteAVSDK_Player/TXLiteAVSDK.h> #import <TXLiteAVSDK_Player/TXLiteAVSDK.h>
...@@ -11,3 +14,5 @@ static int maxCacheItems = -1; ...@@ -11,3 +14,5 @@ static int maxCacheItems = -1;
+ (TXLivePlayConfig *)transformToLiveConfig:(NSDictionary*)map; + (TXLivePlayConfig *)transformToLiveConfig:(NSDictionary*)map;
@end @end
#endif // SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXTRANSFORMATION_H_
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
#ifndef SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXVODPLAYER_H_
#define SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXVODPLAYER_H_
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "FTXBasePlayer.h" #import "FTXBasePlayer.h"
...@@ -25,10 +27,12 @@ NS_ASSUME_NONNULL_BEGIN ...@@ -25,10 +27,12 @@ NS_ASSUME_NONNULL_BEGIN
@interface FTXVodPlayer : FTXBasePlayer @interface FTXVodPlayer : FTXBasePlayer
@property (nonatomic, weak) id<FTXVodPlayerDelegate> delegate; @property(nonatomic, weak) id<FTXVodPlayerDelegate> delegate;
- (instancetype)initWithRegistrar:(id<FlutterPluginRegistrar>)registrar; - (instancetype)initWithRegistrar:(id<FlutterPluginRegistrar>)registrar;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END
#endif // SUPERPLAYER_FLUTTER_IOS_CLASSES_FTXVODPLAYER_H_
// Copyright (c) 2022 Tencent. All rights reserved. // Copyright (c) 2022 Tencent. All rights reserved.
#ifndef SUPERPLAYER_FLUTTER_IOS_CLASSES_SUPERPLAYERPLUGIN_H_
#define SUPERPLAYER_FLUTTER_IOS_CLASSES_SUPERPLAYERPLUGIN_H_
#import <Flutter/Flutter.h> #import <Flutter/Flutter.h>
@interface SuperPlayerPlugin : NSObject<FlutterPlugin> @interface SuperPlayerPlugin : NSObject<FlutterPlugin>
@end @end
#endif // SUPERPLAYER_FLUTTER_IOS_CLASSES_SUPERPLAYERPLUGIN_H_
...@@ -3,6 +3,7 @@ part of SuperPlayer; ...@@ -3,6 +3,7 @@ part of SuperPlayer;
class TXLivePlayerController extends ChangeNotifier implements ValueListenable<TXPlayerValue?>, TXPlayerController { class TXLivePlayerController extends ChangeNotifier implements ValueListenable<TXPlayerValue?>, TXPlayerController {
int? _playerId = -1; int? _playerId = -1;
static String kTag = "TXLivePlayerController";
final Completer<int> _initPlayer; final Completer<int> _initPlayer;
final Completer<int> _createTexture; final Completer<int> _createTexture;
...@@ -127,11 +128,17 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -127,11 +128,17 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
_stateStreamController.add(_state); _stateStreamController.add(_state);
} }
void printVersionInfo() async {
LogUtils.d(kTag, "dart SDK version:${Platform.version}");
LogUtils.d(kTag, "liteAV SDK version:${await SuperPlayerPlugin.platformVersion}");
}
/// ///
/// 当设置[LivePlayer] 类型播放器时,需要参数[playType] /// 当设置[LivePlayer] 类型播放器时,需要参数[playType]
/// 参考: [PlayType.LIVE_RTMP] ... /// 参考: [PlayType.LIVE_RTMP] ...
@deprecated @deprecated
Future<bool> play(String url, {int? playType}) async { Future<bool> play(String url, {int? playType}) async {
printVersionInfo();
return await startLivePlay(url, playType: playType); return await startLivePlay(url, playType: playType);
} }
...@@ -146,7 +153,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T ...@@ -146,7 +153,7 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
await _initPlayer.future; await _initPlayer.future;
await _createTexture.future; await _createTexture.future;
_changeState(TXPlayerState.buffering); _changeState(TXPlayerState.buffering);
printVersionInfo();
final result = await _channel.invokeMethod("startLivePlay", {"url": url, "playType": playType}); final result = await _channel.invokeMethod("startLivePlay", {"url": url, "playType": playType});
return result == 0; return result == 0;
} }
......
...@@ -3,6 +3,7 @@ part of SuperPlayer; ...@@ -3,6 +3,7 @@ part of SuperPlayer;
class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TXPlayerValue?>, TXPlayerController { class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TXPlayerValue?>, TXPlayerController {
int? _playerId = -1; int? _playerId = -1;
static String kTag = "TXVodPlayerController";
final Completer<int> _initPlayer; final Completer<int> _initPlayer;
final Completer<int> _createTexture; final Completer<int> _createTexture;
...@@ -137,6 +138,11 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX ...@@ -137,6 +138,11 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
_stateStreamController.add(_state); _stateStreamController.add(_state);
} }
void printVersionInfo() async {
LogUtils.d(kTag, "dart SDK version:${Platform.version}");
LogUtils.d(kTag, "liteAV SDK version:${await SuperPlayerPlugin.platformVersion}");
}
/// 通过url开始播放视频 /// 通过url开始播放视频
/// 10.7版本开始,startPlay变更为startVodPlay,需要通过 {@link SuperPlayerPlugin#setGlobalLicense} 设置 Licence 后方可成功播放, /// 10.7版本开始,startPlay变更为startVodPlay,需要通过 {@link SuperPlayerPlugin#setGlobalLicense} 设置 Licence 后方可成功播放,
/// 否则将播放失败(黑屏),全局仅设置一次即可。直播 Licence、短视频 Licence 和视频播放 Licence 均可使用,若您暂未获取上述 Licence , /// 否则将播放失败(黑屏),全局仅设置一次即可。直播 Licence、短视频 Licence 和视频播放 Licence 均可使用,若您暂未获取上述 Licence ,
...@@ -148,7 +154,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX ...@@ -148,7 +154,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
await _initPlayer.future; await _initPlayer.future;
await _createTexture.future; await _createTexture.future;
_changeState(TXPlayerState.buffering); _changeState(TXPlayerState.buffering);
printVersionInfo();
final result = await _channel.invokeMethod("startVodPlay", {"url": url}); final result = await _channel.invokeMethod("startVodPlay", {"url": url});
return result == 0; return result == 0;
} }
...@@ -164,7 +170,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX ...@@ -164,7 +170,7 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
await _initPlayer.future; await _initPlayer.future;
await _createTexture.future; await _createTexture.future;
_changeState(TXPlayerState.buffering); _changeState(TXPlayerState.buffering);
printVersionInfo();
await _channel.invokeMethod("startVodPlayWithParams", params.toJson()); await _channel.invokeMethod("startVodPlayWithParams", params.toJson());
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
part of demo_super_player_lib; part of demo_super_player_lib;
typedef OnJumpToPipPlayer = void Function(Map params); typedef OnJumpToPipPlayer = void Function(Map params);
typedef OnPopCurrent = void Function(); typedef OnPipClose = void Function();
/// ///
/// 画中画控制器,单例,只能存在一个画中画 /// 画中画控制器,单例,只能存在一个画中画
...@@ -19,6 +19,7 @@ class TXPipController { ...@@ -19,6 +19,7 @@ class TXPipController {
final Map<String, dynamic> _extParams = {}; final Map<String, dynamic> _extParams = {};
TXPipPlayerRestorePage? _onPipEnterListener; TXPipPlayerRestorePage? _onPipEnterListener;
OnJumpToPipPlayer? _onJumpToPipPlayer; OnJumpToPipPlayer? _onJumpToPipPlayer;
OnPipClose? _onPipClose;
StreamSubscription? _pipEventSubscription; StreamSubscription? _pipEventSubscription;
/// TXPipController /// TXPipController
...@@ -44,7 +45,11 @@ class TXPipController { ...@@ -44,7 +45,11 @@ class TXPipController {
(Platform.isAndroid && eventCode == TXVodPlayEvent.EVENT_PIP_MODE_REQUEST_START)) { (Platform.isAndroid && eventCode == TXVodPlayEvent.EVENT_PIP_MODE_REQUEST_START)) {
_onPipEnterListener?.onNeedSavePipPageState(_extParams); _onPipEnterListener?.onNeedSavePipPageState(_extParams);
_playerData?.isEnterPip = true; _playerData?.isEnterPip = true;
Navigator.of(context).pop(); if(_onPipClose != null) {
_onPipClose!.call();
} else {
Navigator.of(context).pop();
}
} else if ((Platform.isIOS && eventCode == TXVodPlayEvent.EVENT_IOS_PIP_MODE_WILL_EXIT) || } else if ((Platform.isIOS && eventCode == TXVodPlayEvent.EVENT_IOS_PIP_MODE_WILL_EXIT) ||
(Platform.isAndroid && eventCode == TXVodPlayEvent.EVENT_PIP_MODE_ALREADY_EXIT)) { (Platform.isAndroid && eventCode == TXVodPlayEvent.EVENT_PIP_MODE_ALREADY_EXIT)) {
_playerData?.isEnterPip = false; _playerData?.isEnterPip = false;
...@@ -100,8 +105,9 @@ class TXPipController { ...@@ -100,8 +105,9 @@ class TXPipController {
_onPipEnterListener = listener; _onPipEnterListener = listener;
} }
void setNavigatorHandle(OnJumpToPipPlayer onJumpToPipPlayer) { void setNavigatorHandle(OnJumpToPipPlayer onJumpToPipPlayer,{OnPipClose? onPipClose}) {
_onJumpToPipPlayer = onJumpToPipPlayer; _onJumpToPipPlayer = onJumpToPipPlayer;
_onPipClose = onPipClose;
} }
} }
......
...@@ -78,6 +78,7 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs ...@@ -78,6 +78,7 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs
_coverViewController = CoverViewController(_onDoubleTapVideo, _onSingleTapVideo); _coverViewController = CoverViewController(_onDoubleTapVideo, _onSingleTapVideo);
_qualitListViewController = QualityListViewController((quality) { _qualitListViewController = QualityListViewController((quality) {
_playController.switchStream(quality); _playController.switchStream(quality);
hideControlView();
}); });
_moreViewController = MoreViewController( _moreViewController = MoreViewController(
() => _playController._isOpenHWAcceleration, () => _playController._isOpenHWAcceleration,
...@@ -181,6 +182,7 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs ...@@ -181,6 +182,7 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs
}, (code, msg) { }, (code, msg) {
// onError // onError
_togglePlayUIState(false); _togglePlayUIState(false);
EasyLoading.showToast("play video error,code:$code,error:$msg");
}, (playerType) { }, (playerType) {
// onPlayerTypeChange // onPlayerTypeChange
_videoBottomKey.currentState?.updatePlayerType(playerType); _videoBottomKey.currentState?.updatePlayerType(playerType);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论