提交 a6617380 authored 作者: kongdywang's avatar kongdywang

1. android pip optimize

2. superPlayerWidget pos changed 3. unified plugin log output 4. fix known issues
上级 fa52f557
#!/usr/bin/env bash
buildLog() {
echo `date +"%Y-%m-%d %H:%M:%S"`" build process: $1"
}
inputVersion=$1
export VERSION_NAME="11.8.1"
if [ -n "$inputVersion" ]; then
VERSION_NAME=$inputVersion
fi
buildLog "start config Version=${VERSION_NAME}"
buildLog "currentPathIs:$(pwd)"
buildLog "start config flutter lib pubspec version"
sed -i "" "s/version:.*$/version: $VERSION_NAME/" ../pubspec.yaml
buildLog "config success on flutter lib pubspec version"
buildLog "start config flutter lib code version"
sed -i "" "s/PLAYER_VERSION = \"[0-9.]*\"/PLAYER_VERSION = \"$VERSION_NAME\"/" ../lib/Core/common/common_config.dart
buildLog "config success on flutter lib code version"
buildLog "start config flutter superplayer_widget pubspec version"
sed -i "" "s/version:.*$/version: $VERSION_NAME/" ../superplayer_widget/pubspec.yaml
buildLog "config success on superplayer_widget pubspec version"
buildLog "start config plugin android version"
sed -i "" "s/playerVersion = \"[0-9.]*\"/playerVersion = \"$VERSION_NAME\"/" ../android/config.gradle
buildLog "config success on plugin android version"
buildLog "start config plugin ios version"
sed -i "" "s/s.version = '[0-9.]*'/s.version = '$VERSION_NAME'/" ../ios/super_player.podspec
buildLog "config success on plugin ios version"
buildLog "config Version=${VERSION_NAME} done"
\ No newline at end of file
...@@ -23,6 +23,7 @@ rootProject.allprojects { ...@@ -23,6 +23,7 @@ rootProject.allprojects {
android { android {
compileSdkVersion rootProject.ext.compileSdkVersion compileSdkVersion rootProject.ext.compileSdkVersion
namespace="com.tencent.vod.flutter"
defaultConfig { defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<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.tencent.vod.flutter">
<uses-permission android:name="android.permission.REORDER_TASKS" /> <uses-permission android:name="android.permission.REORDER_TASKS" />
<application> <application>
......
...@@ -9,7 +9,8 @@ import android.media.AudioManager; ...@@ -9,7 +9,8 @@ import android.media.AudioManager;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log;
import com.tencent.liteav.base.util.LiteavLog;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -147,7 +148,7 @@ public class FTXAudioManager { ...@@ -147,7 +148,7 @@ public class FTXAudioManager {
result = mAudioManager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC, result = mAudioManager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN); AudioManager.AUDIOFOCUS_GAIN);
} }
Log.e(TAG, "requestAudioFocus result:" + result); LiteavLog.e(TAG, "requestAudioFocus result:" + result);
} }
public void addAudioFocusChangedListener(AudioFocusChangeListener listener) { public void addAudioFocusChangedListener(AudioFocusChangeListener listener) {
......
...@@ -94,6 +94,12 @@ public class FTXEvent { ...@@ -94,6 +94,12 @@ public class FTXEvent {
// PIP error, current interface has been destroyed. // PIP error, current interface has been destroyed.
// pip 错误,当前界面已销毁 // pip 错误,当前界面已销毁
public static final int ERROR_PIP_ACTIVITY_DESTROYED = -103; public static final int ERROR_PIP_ACTIVITY_DESTROYED = -103;
// PIP error, miss player
// pip 错误,丢失播放器
public static final int ERROR_PIP_MISS_PLAYER = -104;
// PIP error, pip is busy
// pip 错误,已经存在画中画窗口
public static final int ERROR_PIP_IN_BUSY = -105;
// Event from PIP container,eventBus key value // Event from PIP container,eventBus key value
// 来自画中画容器的事件,eventBus键值 // 来自画中画容器的事件,eventBus键值
public static final String EVENT_PIP_ACTION = "com.tencent.flutter.pipevent"; public static final String EVENT_PIP_ACTION = "com.tencent.flutter.pipevent";
...@@ -134,9 +140,6 @@ public class FTXEvent { ...@@ -134,9 +140,6 @@ public class FTXEvent {
// PIP parameters. // PIP parameters.
// 画中画参数 // 画中画参数
public static final String EXTRA_NAME_PARAMS = "pipParams"; public static final String EXTRA_NAME_PARAMS = "pipParams";
// Video source.
// 视频源
public static final String EXTRA_NAME_VIDEO = "videoModel";
// End parameters of PIP. // End parameters of PIP.
// 画中画结束参数 // 画中画结束参数
public static final String EXTRA_NAME_RESULT = "pipResult"; public static final String EXTRA_NAME_RESULT = "pipResult";
......
...@@ -4,16 +4,17 @@ package com.tencent.vod.flutter; ...@@ -4,16 +4,17 @@ package com.tencent.vod.flutter;
import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.view.Surface; import android.view.Surface;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.tencent.liteav.base.util.LiteavLog;
import com.tencent.rtmp.ITXLivePlayListener; import com.tencent.rtmp.ITXLivePlayListener;
import com.tencent.rtmp.TXLiveBase; import com.tencent.rtmp.TXLiveBase;
import com.tencent.rtmp.TXLiveConstants; import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLivePlayConfig; import com.tencent.rtmp.TXLivePlayConfig;
import com.tencent.rtmp.TXLivePlayer; import com.tencent.rtmp.TXLivePlayer;
import com.tencent.rtmp.TXVodConstants; import com.tencent.rtmp.TXVodConstants;
import com.tencent.rtmp.TXVodPlayer;
import com.tencent.vod.flutter.messages.FtxMessages.BoolMsg; import com.tencent.vod.flutter.messages.FtxMessages.BoolMsg;
import com.tencent.vod.flutter.messages.FtxMessages.BoolPlayerMsg; import com.tencent.vod.flutter.messages.FtxMessages.BoolPlayerMsg;
import com.tencent.vod.flutter.messages.FtxMessages.FTXLivePlayConfigPlayerMsg; import com.tencent.vod.flutter.messages.FtxMessages.FTXLivePlayConfigPlayerMsg;
...@@ -25,8 +26,9 @@ import com.tencent.vod.flutter.messages.FtxMessages.StringIntPlayerMsg; ...@@ -25,8 +26,9 @@ import com.tencent.vod.flutter.messages.FtxMessages.StringIntPlayerMsg;
import com.tencent.vod.flutter.messages.FtxMessages.StringPlayerMsg; import com.tencent.vod.flutter.messages.FtxMessages.StringPlayerMsg;
import com.tencent.vod.flutter.messages.FtxMessages.TXFlutterLivePlayerApi; import com.tencent.vod.flutter.messages.FtxMessages.TXFlutterLivePlayerApi;
import com.tencent.vod.flutter.model.TXPipResult; import com.tencent.vod.flutter.model.TXPipResult;
import com.tencent.vod.flutter.model.TXVideoModel; import com.tencent.vod.flutter.model.TXPlayerHolder;
import com.tencent.vod.flutter.tools.TXCommonUtil; import com.tencent.vod.flutter.tools.TXCommonUtil;
import com.tencent.vod.flutter.tools.TXFlutterEngineHolder;
import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.EventChannel;
...@@ -59,16 +61,23 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener, ...@@ -59,16 +61,23 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener,
private int mSurfaceHeight = 0; private int mSurfaceHeight = 0;
private final FTXPIPManager mPipManager; private final FTXPIPManager mPipManager;
private FTXPIPManager.PipParams mPipParams; private boolean mNeedPipResume = false;
private TXVideoModel mVideoModel;
private final FTXPIPManager.PipCallback pipCallback = new FTXPIPManager.PipCallback() { private final FTXPIPManager.PipCallback pipCallback = new FTXPIPManager.PipCallback() {
@Override @Override
public void onPipResult(TXPipResult result) { public void onPipResult(TXPipResult result) {
// When starting PIP, if the current player is paused and PIP is still playing when exiting, if (mLivePlayer != null) {
// the current player will also be set to playing state upon exiting PIP. mLivePlayer.setSurface(mSurface);
mLivePlayer.setPlayListener(FTXLivePlayer.this);
}
// When starting PIP, the current player has been paused. After PIP exits,
// if PIP is still in playing state, the current player will also be set to playing state.
boolean isPipPlaying = result.isPlaying(); boolean isPipPlaying = result.isPlaying();
if (isPipPlaying) { if (isPipPlaying) {
if (TXFlutterEngineHolder.getInstance().isInForeground()) {
resumePlayer(); resumePlayer();
} else {
mNeedPipResume = true;
}
} }
} }
...@@ -78,6 +87,21 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener, ...@@ -78,6 +87,21 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener,
} }
}; };
private final TXFlutterEngineHolder.TXAppStatusListener mAppLifeListener
= new TXFlutterEngineHolder.TXAppStatusListener() {
@Override
public void onResume() {
if (mNeedPipResume) {
mNeedPipResume = false;
resumePlayer();
}
}
@Override
public void onEnterBack() {
}
};
/** /**
* Live streaming player. * Live streaming player.
* *
...@@ -87,8 +111,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener, ...@@ -87,8 +111,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener,
super(); super();
mFlutterPluginBinding = flutterPluginBinding; mFlutterPluginBinding = flutterPluginBinding;
mPipManager = pipManager; mPipManager = pipManager;
mVideoModel = new TXVideoModel(); TXFlutterEngineHolder.getInstance().addAppLifeListener(mAppLifeListener);
mVideoModel.setPlayerType(FTXEvent.PLAYER_LIVE);
mSurfaceTextureEntry = mFlutterPluginBinding.getTextureRegistry().createSurfaceTexture(); mSurfaceTextureEntry = mFlutterPluginBinding.getTextureRegistry().createSurfaceTexture();
mSurfaceTexture = mSurfaceTextureEntry.surfaceTexture(); mSurfaceTexture = mSurfaceTextureEntry.surfaceTexture();
...@@ -145,6 +168,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener, ...@@ -145,6 +168,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener,
mSurface = null; mSurface = null;
} }
TXFlutterEngineHolder.getInstance().removeAppLifeListener(mAppLifeListener);
mEventChannel.setStreamHandler(null); mEventChannel.setStreamHandler(null);
mNetChannel.setStreamHandler(null); mNetChannel.setStreamHandler(null);
} }
...@@ -161,7 +185,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener, ...@@ -161,7 +185,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener,
mHardwareDecodeFail = true; mHardwareDecodeFail = true;
} }
if (event != TXVodConstants.VOD_PLAY_EVT_PLAY_PROGRESS) { if (event != TXVodConstants.VOD_PLAY_EVT_PLAY_PROGRESS) {
Log.e(TAG, "onLivePlayEvent:" + event + "," + bundle.getString(TXLiveConstants.EVT_DESCRIPTION)); LiteavLog.e(TAG, "onLivePlayEvent:" + event + "," + bundle.getString(TXLiveConstants.EVT_DESCRIPTION));
} }
mEventSink.success(TXCommonUtil.getParams(event, bundle)); mEventSink.success(TXCommonUtil.getParams(event, bundle));
} }
...@@ -192,17 +216,15 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener, ...@@ -192,17 +216,15 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener,
mLivePlayer = new TXLivePlayer(mFlutterPluginBinding.getApplicationContext()); mLivePlayer = new TXLivePlayer(mFlutterPluginBinding.getApplicationContext());
mLivePlayer.setPlayListener(this); mLivePlayer.setPlayListener(this);
} }
Log.d("AndroidLog", "textureId :" + mSurfaceTextureEntry.id()); LiteavLog.d("AndroidLog", "textureId :" + mSurfaceTextureEntry.id());
return mSurfaceTextureEntry == null ? -1 : mSurfaceTextureEntry.id(); return mSurfaceTextureEntry == null ? -1 : mSurfaceTextureEntry.id();
} }
int startPlayerLivePlay(String url, Integer type) { int startPlayerLivePlay(String url, Integer type) {
Log.d(TAG, "startLivePlay:"); LiteavLog.d(TAG, "startLivePlay:");
if (null == type) { if (null == type) {
type = TXLivePlayer.PLAY_TYPE_LIVE_FLV; type = TXLivePlayer.PLAY_TYPE_LIVE_FLV;
} }
mVideoModel.setVideoUrl(url);
mVideoModel.setLiveType(type);
if (mLivePlayer != null) { if (mLivePlayer != null) {
mLivePlayer.setSurface(mSurface); mLivePlayer.setSurface(mSurface);
mLivePlayer.setPlayListener(this); mLivePlayer.setPlayListener(this);
...@@ -215,7 +237,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener, ...@@ -215,7 +237,7 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener,
int width = texture.width; int width = texture.width;
int height = texture.height; int height = texture.height;
if (width != mSurfaceWidth || height != mSurfaceHeight) { if (width != mSurfaceWidth || height != mSurfaceHeight) {
Log.d(TAG, "onRenderVideoFrame: width=" + texture.width + ",height=" + texture.height); LiteavLog.d(TAG, "onRenderVideoFrame: width=" + texture.width + ",height=" + texture.height);
mLivePlayer.setSurfaceSize(width, height); mLivePlayer.setSurfaceSize(width, height);
mSurfaceTexture.setDefaultBufferSize(width, height); mSurfaceTexture.setDefaultBufferSize(width, height);
mSurfaceWidth = width; mSurfaceWidth = width;
...@@ -429,14 +451,14 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener, ...@@ -429,14 +451,14 @@ public class FTXLivePlayer extends FTXBasePlayer implements ITXLivePlayListener,
@Override @Override
public IntMsg enterPictureInPictureMode(@NonNull PipParamsPlayerMsg pipParamsMsg) { public IntMsg enterPictureInPictureMode(@NonNull PipParamsPlayerMsg pipParamsMsg) {
mPipManager.addCallback(getPlayerId(), pipCallback); mPipManager.addCallback(getPlayerId(), pipCallback);
mPipParams = new FTXPIPManager.PipParams( FTXPIPManager.PipParams pipParams = new FTXPIPManager.PipParams(
mPipManager.toAndroidPath(pipParamsMsg.getBackIconForAndroid()), mPipManager.toAndroidPath(pipParamsMsg.getBackIconForAndroid()),
mPipManager.toAndroidPath(pipParamsMsg.getPlayIconForAndroid()), mPipManager.toAndroidPath(pipParamsMsg.getPlayIconForAndroid()),
mPipManager.toAndroidPath(pipParamsMsg.getPauseIconForAndroid()), mPipManager.toAndroidPath(pipParamsMsg.getPauseIconForAndroid()),
mPipManager.toAndroidPath(pipParamsMsg.getForwardIconForAndroid()), mPipManager.toAndroidPath(pipParamsMsg.getForwardIconForAndroid()),
getPlayerId(), false, false, true); getPlayerId(), false, false, true);
mPipParams.setIsPlaying(isPlayerPlaying()); pipParams.setIsPlaying(isPlayerPlaying());
int pipResult = mPipManager.enterPip(mPipParams, mVideoModel); int pipResult = mPipManager.enterPip(pipParams, new TXPlayerHolder(mLivePlayer));
// After the startup is successful, pause the video on the current interface. // After the startup is successful, pause the video on the current interface.
if (pipResult == FTXEvent.NO_ERROR) { if (pipResult == FTXEvent.NO_ERROR) {
pausePlayer(); pausePlayer();
......
...@@ -20,14 +20,14 @@ import android.os.Bundle; ...@@ -20,14 +20,14 @@ import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.Rational; import android.util.Rational;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import com.tencent.liteav.base.util.LiteavLog;
import com.tencent.vod.flutter.model.TXPipResult; import com.tencent.vod.flutter.model.TXPipResult;
import com.tencent.vod.flutter.model.TXVideoModel; import com.tencent.vod.flutter.model.TXPlayerHolder;
import com.tencent.vod.flutter.tools.TXCommonUtil; import com.tencent.vod.flutter.tools.TXCommonUtil;
import com.tencent.vod.flutter.tools.TXSimpleEventBus; import com.tencent.vod.flutter.tools.TXSimpleEventBus;
import com.tencent.vod.flutter.ui.FlutterPipImplActivity; import com.tencent.vod.flutter.ui.FlutterPipImplActivity;
...@@ -127,15 +127,13 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber { ...@@ -127,15 +127,13 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber {
* *
* @return {@link FTXEvent} ERROR_PIP * @return {@link FTXEvent} ERROR_PIP
*/ */
public int enterPip(PipParams params, TXVideoModel videoModel) { public int enterPip(PipParams params, TXPlayerHolder playerHolder) {
int pipResult = isSupportDevice(); int pipResult = isSupportDevice();
if (pipResult == FTXEvent.NO_ERROR) {
pipResult = FlutterPipImplActivity.startPip(mActivityBinding.getActivity(), params, playerHolder);
if (pipResult == FTXEvent.NO_ERROR) { if (pipResult == FTXEvent.NO_ERROR) {
mPipEventSink.success(TXCommonUtil.getParams(FTXEvent.EVENT_PIP_MODE_REQUEST_START, null)); mPipEventSink.success(TXCommonUtil.getParams(FTXEvent.EVENT_PIP_MODE_REQUEST_START, null));
Intent intent = new Intent(mActivityBinding.getActivity(), FlutterPipImplActivity.class); }
intent.setAction(FTXEvent.PIP_ACTION_START);
intent.putExtra(FTXEvent.EXTRA_NAME_PARAMS, params);
intent.putExtra(FTXEvent.EXTRA_NAME_VIDEO, videoModel);
mActivityBinding.getActivity().startActivity(intent);
mIsInPipMode = true; mIsInPipMode = true;
} }
return pipResult; return pipResult;
...@@ -170,19 +168,20 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber { ...@@ -170,19 +168,20 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber {
activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE); activity.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE);
if (!isSuccess) { if (!isSuccess) {
pipResult = FTXEvent.ERROR_PIP_DENIED_PERMISSION; pipResult = FTXEvent.ERROR_PIP_DENIED_PERMISSION;
Log.e(TAG, "enterPip failed,because PIP feature is disabled"); LiteavLog.e(TAG, "enterPip failed,because PIP feature is disabled");
} else if (!hasPipPermission(activity)) { } else if (!hasPipPermission(activity)) {
pipResult = FTXEvent.ERROR_PIP_DENIED_PERMISSION; pipResult = FTXEvent.ERROR_PIP_DENIED_PERMISSION;
Log.e(TAG, "enterPip failed,because PIP has no permission"); LiteavLog.e(TAG, "enterPip failed,because PIP has no permission");
} }
} 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 " LiteavLog.e(TAG, "enterPip failed,because android version is too low,"
+ "24,but current is " + Build.VERSION.SDK_INT); + "Minimum supported version is android 24,but current is "
+ Build.VERSION.SDK_INT);
} }
} else { } else {
pipResult = FTXEvent.ERROR_PIP_ACTIVITY_DESTROYED; pipResult = FTXEvent.ERROR_PIP_ACTIVITY_DESTROYED;
Log.e(TAG, "enterPip failed,because activity is destroyed"); LiteavLog.e(TAG, "enterPip failed,because activity is destroyed");
} }
return pipResult; return pipResult;
} }
...@@ -229,7 +228,7 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber { ...@@ -229,7 +228,7 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber {
TXSimpleEventBus.getInstance().unregister(FTXEvent.EVENT_PIP_PLAYER_EVENT_ACTION, this); TXSimpleEventBus.getInstance().unregister(FTXEvent.EVENT_PIP_PLAYER_EVENT_ACTION, this);
} }
} catch (Exception e) { } catch (Exception e) {
Log.getStackTraceString(e); LiteavLog.e(TAG, "releaseActivityListener error", e);
} }
} }
...@@ -262,9 +261,10 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber { ...@@ -262,9 +261,10 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber {
|| pipEventId == FTXEvent.EVENT_PIP_MODE_RESTORE_UI)) { || pipEventId == FTXEvent.EVENT_PIP_MODE_RESTORE_UI)) {
TXPipResult pipResult = params.getParcelable(FTXEvent.EXTRA_NAME_RESULT); TXPipResult pipResult = params.getParcelable(FTXEvent.EXTRA_NAME_RESULT);
if (null != pipResult) { if (null != pipResult) {
callbackData.putDouble(FTXEvent.EVENT_PIP_PLAY_TIME, pipResult.getPlayTime()); callbackData.putFloat(FTXEvent.EVENT_PIP_PLAY_TIME, pipResult.getPlayTime());
handlePipResult(pipResult); handlePipResult(pipResult);
} }
mIsInPipMode = false;
} }
mPipEventSink.success(TXCommonUtil.getParams(pipEventId, callbackData)); mPipEventSink.success(TXCommonUtil.getParams(pipEventId, callbackData));
} else if (TextUtils.equals(eventType, FTXEvent.EVENT_PIP_PLAYER_EVENT_ACTION)) { } else if (TextUtils.equals(eventType, FTXEvent.EVENT_PIP_PLAYER_EVENT_ACTION)) {
...@@ -474,7 +474,7 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber { ...@@ -474,7 +474,7 @@ public class FTXPIPManager implements TXSimpleEventBus.EventSubscriber {
return Icon.createWithBitmap(iconBitmap); return Icon.createWithBitmap(iconBitmap);
} }
} catch (IOException e) { } catch (IOException e) {
Log.getStackTraceString(e); LiteavLog.e(TAG, "getIcon error", e);
} }
return Icon.createWithResource(activity, defaultResId); return Icon.createWithResource(activity, defaultResId);
} }
......
...@@ -6,9 +6,11 @@ import android.graphics.Bitmap; ...@@ -6,9 +6,11 @@ import android.graphics.Bitmap;
import android.graphics.SurfaceTexture; import android.graphics.SurfaceTexture;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.Surface; import android.view.Surface;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.tencent.liteav.base.util.LiteavLog;
import com.tencent.rtmp.ITXVodPlayListener; import com.tencent.rtmp.ITXVodPlayListener;
import com.tencent.rtmp.TXBitrateItem; import com.tencent.rtmp.TXBitrateItem;
import com.tencent.rtmp.TXImageSprite; import com.tencent.rtmp.TXImageSprite;
...@@ -36,8 +38,9 @@ import com.tencent.vod.flutter.messages.FtxMessages.StringPlayerMsg; ...@@ -36,8 +38,9 @@ import com.tencent.vod.flutter.messages.FtxMessages.StringPlayerMsg;
import com.tencent.vod.flutter.messages.FtxMessages.TXPlayInfoParamsPlayerMsg; import com.tencent.vod.flutter.messages.FtxMessages.TXPlayInfoParamsPlayerMsg;
import com.tencent.vod.flutter.messages.FtxMessages.UInt8ListMsg; import com.tencent.vod.flutter.messages.FtxMessages.UInt8ListMsg;
import com.tencent.vod.flutter.model.TXPipResult; import com.tencent.vod.flutter.model.TXPipResult;
import com.tencent.vod.flutter.model.TXVideoModel; import com.tencent.vod.flutter.model.TXPlayerHolder;
import com.tencent.vod.flutter.tools.TXCommonUtil; import com.tencent.vod.flutter.tools.TXCommonUtil;
import com.tencent.vod.flutter.tools.TXFlutterEngineHolder;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
...@@ -49,7 +52,6 @@ import java.util.Map; ...@@ -49,7 +52,6 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.EventChannel;
import io.flutter.view.TextureRegistry; import io.flutter.view.TextureRegistry;
...@@ -73,29 +75,30 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -73,29 +75,30 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
private TXVodPlayer mVodPlayer; private TXVodPlayer mVodPlayer;
private TXImageSprite mTxImageSprite; private TXImageSprite mTxImageSprite;
private TXVideoModel mVideoModel;
private static final int Uninitialized = -101; private static final int Uninitialized = -101;
private TextureRegistry.SurfaceTextureEntry mSurfaceTextureEntry; private TextureRegistry.SurfaceTextureEntry mSurfaceTextureEntry;
private boolean mEnableHardwareDecode = true; private boolean mEnableHardwareDecode = true;
private boolean mHardwareDecodeFail = false; private boolean mHardwareDecodeFail = false;
private final FTXPIPManager mPipManager; private final FTXPIPManager mPipManager;
private FTXPIPManager.PipParams mPipParams; private boolean mNeedPipResume = false;
private final FTXPIPManager.PipCallback pipCallback = new FTXPIPManager.PipCallback() { private final FTXPIPManager.PipCallback mPipCallback = new FTXPIPManager.PipCallback() {
@Override @Override
public void onPipResult(TXPipResult result) { public void onPipResult(TXPipResult result) {
float playTime = result.getPlayTime(); if (mVodPlayer != null) {
float duration = mVodPlayer.getDuration(); mSurface = new Surface(mSurfaceTexture);
if (playTime > duration) { mVodPlayer.setSurface(mSurface);
playTime = duration; mVodPlayer.setVodListener(FTXVodPlayer.this);
} }
seekPlayer(playTime);
// When starting PIP, the current player has been paused. After PIP exits, // When starting PIP, the current player has been paused. After PIP exits,
// if PIP is still in playing state, the current player will also be set to playing state. // if PIP is still in playing state, the current player will also be set to playing state.
boolean isPipPlaying = result.isPlaying(); boolean isPipPlaying = result.isPlaying();
if (isPipPlaying) { if (isPipPlaying) {
if (TXFlutterEngineHolder.getInstance().isInForeground()) {
playerResume(); playerResume();
} else {
mNeedPipResume = true;
}
} }
} }
...@@ -105,6 +108,21 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -105,6 +108,21 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
} }
}; };
private final TXFlutterEngineHolder.TXAppStatusListener mAppLifeListener
= new TXFlutterEngineHolder.TXAppStatusListener() {
@Override
public void onResume() {
if (mNeedPipResume) {
mNeedPipResume = false;
playerResume();
}
}
@Override
public void onEnterBack() {
}
};
/** /**
* VOD player. * VOD player.
* *
...@@ -114,8 +132,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -114,8 +132,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
super(); super();
mPipManager = pipManager; mPipManager = pipManager;
mFlutterPluginBinding = flutterPluginBinding; mFlutterPluginBinding = flutterPluginBinding;
mVideoModel = new TXVideoModel(); TXFlutterEngineHolder.getInstance().addAppLifeListener(mAppLifeListener);
mVideoModel.setPlayerType(FTXEvent.PLAYER_VOD);
mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent" mEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "cloud.tencent"
+ ".com/txvodplayer/event/" + super.getPlayerId()); + ".com/txvodplayer/event/" + super.getPlayerId());
...@@ -171,6 +188,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -171,6 +188,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
mEventChannel.setStreamHandler(null); mEventChannel.setStreamHandler(null);
mNetChannel.setStreamHandler(null); mNetChannel.setStreamHandler(null);
TXFlutterEngineHolder.getInstance().removeAppLifeListener(mAppLifeListener);
releaseTXImageSprite(); releaseTXImageSprite();
if (null != mPipManager) { if (null != mPipManager) {
mPipManager.releaseCallback(getPlayerId()); mPipManager.releaseCallback(getPlayerId());
...@@ -212,7 +230,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -212,7 +230,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
mHardwareDecodeFail = true; mHardwareDecodeFail = true;
} }
if (event != TXVodConstants.VOD_PLAY_EVT_PLAY_PROGRESS) { if (event != TXVodConstants.VOD_PLAY_EVT_PLAY_PROGRESS) {
Log.e(TAG, "onPlayEvent:" + event + "," + bundle.getString(TXLiveConstants.EVT_DESCRIPTION)); LiteavLog.e(TAG, "onPlayEvent:" + event + "," + bundle.getString(TXLiveConstants.EVT_DESCRIPTION));
} }
mEventSink.success(TXCommonUtil.getParams(event, bundle)); mEventSink.success(TXCommonUtil.getParams(event, bundle));
} }
...@@ -243,7 +261,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -243,7 +261,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
return stream.toByteArray(); return stream.toByteArray();
} }
} else { } else {
Log.e(TAG, "getImageSprite failed, time is null or initImageSprite not invoke"); LiteavLog.e(TAG, "getImageSprite failed, time is null or initImageSprite not invoke");
} }
return null; return null;
} }
...@@ -291,10 +309,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -291,10 +309,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
int startPlayerVodPlay(String url) { int startPlayerVodPlay(String url) {
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;
...@@ -302,10 +316,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -302,10 +316,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
void startPlayerVodPlayWithParams(int appId, String fileId, String psign) { void startPlayerVodPlayWithParams(int appId, String fileId, String psign) {
if (mVodPlayer != null) { if (mVodPlayer != null) {
mVideoModel.setVideoUrl("");
mVideoModel.setAppId(appId);
mVideoModel.setFileId(fileId);
mVideoModel.setPSign(psign);
TXPlayInfoParams playInfoParams = new TXPlayInfoParams(appId, fileId, psign); TXPlayInfoParams playInfoParams = new TXPlayInfoParams(appId, fileId, psign);
mVodPlayer.startVodPlay(playInfoParams); mVodPlayer.startVodPlay(playInfoParams);
} }
...@@ -315,6 +325,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -315,6 +325,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
if (mVodPlayer != null) { if (mVodPlayer != null) {
return mVodPlayer.stopPlay(isNeedClearLastImg); return mVodPlayer.stopPlay(isNeedClearLastImg);
} }
mPipManager.exitPip();
releaseTXImageSprite(); releaseTXImageSprite();
mHardwareDecodeFail = false; mHardwareDecodeFail = false;
return Uninitialized; return Uninitialized;
...@@ -464,10 +475,8 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -464,10 +475,8 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
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);
} }
} }
} }
...@@ -712,23 +721,24 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F ...@@ -712,23 +721,24 @@ public class FTXVodPlayer extends FTXBasePlayer implements ITXVodPlayListener, F
@NonNull @NonNull
@Override @Override
public IntMsg enterPictureInPictureMode(@NonNull PipParamsPlayerMsg pipParamsMsg) { public IntMsg enterPictureInPictureMode(@NonNull PipParamsPlayerMsg pipParamsMsg) {
mPipManager.addCallback(getPlayerId(), pipCallback); mPipManager.addCallback(getPlayerId(), mPipCallback);
mPipParams = new FTXPIPManager.PipParams( FTXPIPManager.PipParams pipParams = new FTXPIPManager.PipParams(
mPipManager.toAndroidPath(pipParamsMsg.getBackIconForAndroid()), mPipManager.toAndroidPath(pipParamsMsg.getBackIconForAndroid()),
mPipManager.toAndroidPath(pipParamsMsg.getPlayIconForAndroid()), mPipManager.toAndroidPath(pipParamsMsg.getPlayIconForAndroid()),
mPipManager.toAndroidPath(pipParamsMsg.getPauseIconForAndroid()), mPipManager.toAndroidPath(pipParamsMsg.getPauseIconForAndroid()),
mPipManager.toAndroidPath(pipParamsMsg.getForwardIconForAndroid()), mPipManager.toAndroidPath(pipParamsMsg.getForwardIconForAndroid()),
getPlayerId()); getPlayerId());
mPipParams.setIsPlaying(isPlayerPlaying()); pipParams.setIsPlaying(isPlayerPlaying());
mPipParams.setCurrentPlayTime(getPlayerCurrentPlaybackTime()); pipParams.setCurrentPlayTime(getPlayerCurrentPlaybackTime());
int pipResult = FTXEvent.ERROR_PIP_MISS_PLAYER;
if (null != mVodPlayer) { if (null != mVodPlayer) {
mPipParams.setRadio(mVodPlayer.getWidth(), mVodPlayer.getHeight()); pipParams.setRadio(mVodPlayer.getWidth(), mVodPlayer.getHeight());
} pipResult = mPipManager.enterPip(pipParams, new TXPlayerHolder(mVodPlayer));
int pipResult = mPipManager.enterPip(mPipParams, mVideoModel);
// After successful startup, pause the current interface video. // After successful startup, pause the current interface video.
if (pipResult == FTXEvent.NO_ERROR) { if (pipResult == FTXEvent.NO_ERROR) {
playerPause(); playerPause();
} }
}
return TXCommonUtil.intMsgWith((long) pipResult); return TXCommonUtil.intMsgWith((long) pipResult);
} }
......
...@@ -17,7 +17,6 @@ import android.os.Looper; ...@@ -17,7 +17,6 @@ import android.os.Looper;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException; import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.OrientationEventListener; import android.view.OrientationEventListener;
import android.view.Window; import android.view.Window;
...@@ -26,6 +25,7 @@ import android.view.WindowManager; ...@@ -26,6 +25,7 @@ import android.view.WindowManager;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import com.tencent.liteav.base.util.LiteavLog;
import com.tencent.rtmp.TXLiveBase; import com.tencent.rtmp.TXLiveBase;
import com.tencent.rtmp.TXLiveBaseListener; import com.tencent.rtmp.TXLiveBaseListener;
import com.tencent.rtmp.TXPlayerGlobalSetting; import com.tencent.rtmp.TXPlayerGlobalSetting;
...@@ -76,12 +76,12 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -76,12 +76,12 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
private EventChannel mEventChannel; private EventChannel mEventChannel;
private EventChannel mPipEventChannel; private EventChannel mPipEventChannel;
private FTXPlayerEventSink mEventSink = new FTXPlayerEventSink(); private final FTXPlayerEventSink mEventSink = new FTXPlayerEventSink();
private VolumeBroadcastReceiver mVolumeBroadcastReceiver; private VolumeBroadcastReceiver mVolumeBroadcastReceiver;
private FlutterPluginBinding mFlutterPluginBinding; private FlutterPluginBinding mFlutterPluginBinding;
private ActivityPluginBinding mActivityPluginBinding; private ActivityPluginBinding mActivityPluginBinding;
private SparseArray<FTXBasePlayer> mPlayers; private final SparseArray<FTXBasePlayer> mPlayers = new SparseArray<>();
private FTXDownloadManager mFTXDownloadManager; private FTXDownloadManager mFTXDownloadManager;
private FTXAudioManager mTxAudioManager; private FTXAudioManager mTxAudioManager;
...@@ -89,9 +89,8 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -89,9 +89,8 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
private OrientationEventListener mOrientationManager; private OrientationEventListener mOrientationManager;
private int mCurrentOrientation = FTXEvent.ORIENTATION_PORTRAIT_UP; private int mCurrentOrientation = FTXEvent.ORIENTATION_PORTRAIT_UP;
private final TXFlutterEngineHolder mEngineHolder = new TXFlutterEngineHolder();
private boolean mIsBrightnessObserverRegistered = false; private boolean mIsBrightnessObserverRegistered = false;
private Handler mMainHandler = new Handler(Looper.getMainLooper()); private final Handler mMainHandler = new Handler(Looper.getMainLooper());
private final FTXAudioManager.AudioFocusChangeListener audioFocusChangeListener = private final FTXAudioManager.AudioFocusChangeListener audioFocusChangeListener =
new FTXAudioManager.AudioFocusChangeListener() { new FTXAudioManager.AudioFocusChangeListener() {
...@@ -116,15 +115,15 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -116,15 +115,15 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
private final TXLiveBaseListener mSDKEvent = new TXLiveBaseListener() { private final TXLiveBaseListener mSDKEvent = new TXLiveBaseListener() {
@Override @Override
public void onLog(int level, String module, String log) { public void onLog(int level, String module, String liteavLog) {
super.onLog(level, module, log); super.onLog(level, module, liteavLog);
// mMainHandler.post(new Runnable() { // mMainHandler.post(new Runnable() {
// @Override // @Override
// public void run() { // public void run() {
// Bundle params = new Bundle(); // Bundle params = new Bundle();
// params.putInt(FTXEvent.EVENT_LOG_LEVEL, level); // params.putInt(FTXEvent.EVENT_LOG_LEVEL, level);
// params.putString(FTXEvent.EVENT_LOG_MODULE, module); // params.putString(FTXEvent.EVENT_LOG_MODULE, module);
// params.putString(FTXEvent.EVENT_LOG_MSG, log); // params.putString(FTXEvent.EVENT_LOG_MSG, LiteavLog);
// mEventSink.success(getParams(FTXEvent.EVENT_ON_LOG, params)); // mEventSink.success(getParams(FTXEvent.EVENT_ON_LOG, params));
// } // }
// }); // });
...@@ -180,7 +179,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -180,7 +179,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
@Override @Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
Log.i(TAG, "onAttachedToEngine"); LiteavLog.i(TAG, "onAttachedToEngine");
TXFlutterSuperPlayerPluginAPI.setup(flutterPluginBinding.getBinaryMessenger(), this); TXFlutterSuperPlayerPluginAPI.setup(flutterPluginBinding.getBinaryMessenger(), this);
TXFlutterNativeAPI.setup(flutterPluginBinding.getBinaryMessenger(), this); TXFlutterNativeAPI.setup(flutterPluginBinding.getBinaryMessenger(), this);
TXFlutterVodPlayerApi.setup(flutterPluginBinding.getBinaryMessenger(), new FTXVodPlayerDispatcher( TXFlutterVodPlayerApi.setup(flutterPluginBinding.getBinaryMessenger(), new FTXVodPlayerDispatcher(
...@@ -188,7 +187,6 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -188,7 +187,6 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
TXFlutterLivePlayerApi.setup(flutterPluginBinding.getBinaryMessenger(), new FTXLivePlayerDispatcher( TXFlutterLivePlayerApi.setup(flutterPluginBinding.getBinaryMessenger(), new FTXLivePlayerDispatcher(
() -> mPlayers)); () -> mPlayers));
mFlutterPluginBinding = flutterPluginBinding; mFlutterPluginBinding = flutterPluginBinding;
mPlayers = new SparseArray<>();
initAudioManagerIfNeed(); initAudioManagerIfNeed();
mPipEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), mPipEventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(),
FTXEvent.PIP_CHANNEL_NAME); FTXEvent.PIP_CHANNEL_NAME);
...@@ -357,7 +355,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -357,7 +355,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
}; };
mOrientationManager.enable(); mOrientationManager.enable();
} catch (Exception e) { } catch (Exception e) {
Log.getStackTraceString(e); LiteavLog.e(TAG, "innerStartVideoOrientationService error", e);
return false; return false;
} }
} }
...@@ -444,7 +442,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -444,7 +442,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
@Override @Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
Log.i(TAG, "onDetachedFromEngine"); LiteavLog.i(TAG, "onDetachedFromEngine");
mFTXDownloadManager.destroy(); mFTXDownloadManager.destroy();
mFlutterPluginBinding = null; mFlutterPluginBinding = null;
if (null != mOrientationManager) { if (null != mOrientationManager) {
...@@ -455,13 +453,13 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -455,13 +453,13 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
@Override @Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
if (null != mActivityPluginBinding && mActivityPluginBinding != binding) { if (null != mActivityPluginBinding && mActivityPluginBinding != binding) {
mEngineHolder.destroy(binding); TXFlutterEngineHolder.getInstance().destroy(binding);
} }
mActivityPluginBinding = binding; mActivityPluginBinding = binding;
initAudioManagerIfNeed(); initAudioManagerIfNeed();
initPipManagerIfNeed(); initPipManagerIfNeed();
registerReceiver(); registerReceiver();
mEngineHolder.attachBindLife(binding); TXFlutterEngineHolder.getInstance().attachBindLife(binding);
TXLiveBase.enableCustomHttpDNS(true); TXLiveBase.enableCustomHttpDNS(true);
TXLiveBase.setListener(mSDKEvent); TXLiveBase.setListener(mSDKEvent);
} }
...@@ -485,7 +483,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -485,7 +483,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
Intent serviceIntent = new Intent(mActivityPluginBinding.getActivity(), TXAndroid12BridgeService.class); Intent serviceIntent = new Intent(mActivityPluginBinding.getActivity(), TXAndroid12BridgeService.class);
mActivityPluginBinding.getActivity().stopService(serviceIntent); mActivityPluginBinding.getActivity().stopService(serviceIntent);
unregisterReceiver(); unregisterReceiver();
mEngineHolder.destroy(mActivityPluginBinding); TXFlutterEngineHolder.getInstance().destroy(mActivityPluginBinding);
TXLiveBase.setListener(null); TXLiveBase.setListener(null);
} }
...@@ -509,7 +507,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware, ...@@ -509,7 +507,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, ActivityAware,
mFlutterPluginBinding.getApplicationContext().getContentResolver(), mFlutterPluginBinding.getApplicationContext().getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 0) == 1); Settings.System.ACCELEROMETER_ROTATION, 0) == 1);
} catch (Exception e) { } catch (Exception e) {
Log.getStackTraceString(e); LiteavLog.e(TAG, "isDeviceAutoRotateOn error", e);
return false; return false;
} }
} }
......
package com.tencent.vod.flutter.model;
import com.tencent.rtmp.TXLivePlayer;
import com.tencent.rtmp.TXVodPlayer;
import com.tencent.vod.flutter.FTXEvent;
public class TXPlayerHolder {
private TXVodPlayer mVodPlayer;
private TXLivePlayer mLivePlayer;
private int mPlayerType;
private boolean mInitPlayingStatus;
public TXPlayerHolder(TXVodPlayer vodPlayer) {
mVodPlayer = vodPlayer;
mInitPlayingStatus = vodPlayer.isPlaying();
mPlayerType = FTXEvent.PLAYER_VOD;
}
public TXPlayerHolder(TXLivePlayer livePlayer) {
mLivePlayer = livePlayer;
mInitPlayingStatus = livePlayer.isPlaying();
mPlayerType = FTXEvent.PLAYER_LIVE;
}
public TXVodPlayer getVodPlayer() {
return mVodPlayer;
}
public TXLivePlayer getLivePlayer() {
return mLivePlayer;
}
public boolean isPlayingWhenCreate() {
return mInitPlayingStatus;
}
public void tmpPause() {
if (null != mVodPlayer) {
mVodPlayer.pause();
} else if (null != mLivePlayer) {
mLivePlayer.pause();
}
}
public int getPlayerType() {
return mPlayerType;
}
}
// Copyright (c) 2022 Tencent. All rights reserved.
package com.tencent.vod.flutter.model;
import android.os.Parcel;
import android.os.Parcelable;
import com.tencent.rtmp.TXLivePlayer;
import com.tencent.vod.flutter.FTXEvent;
/**
* Video model.
*
* 视频model
*/
public class TXVideoModel implements Parcelable {
private String videoUrl;
private int appId;
private String fileId;
private String pSign;
private int mPlayerType = FTXEvent.PLAYER_VOD;
private int mLiveType = TXLivePlayer.PLAY_TYPE_LIVE_FLV;
private String mToken;
public TXVideoModel() {}
protected TXVideoModel(Parcel in) {
videoUrl = in.readString();
appId = in.readInt();
fileId = in.readString();
pSign = in.readString();
mPlayerType = in.readInt();
mLiveType = in.readInt();
mToken = in.readString();
}
public static final Creator<TXVideoModel> CREATOR = new Creator<TXVideoModel>() {
@Override
public TXVideoModel createFromParcel(Parcel in) {
return new TXVideoModel(in);
}
@Override
public TXVideoModel[] newArray(int size) {
return new TXVideoModel[size];
}
};
public String getVideoUrl() {
return videoUrl;
}
public void setVideoUrl(String videoUrl) {
this.videoUrl = videoUrl;
}
public String getToken() {
return mToken;
}
public void setToken(String token) {
this.mToken = token;
}
public int getAppId() {
return appId;
}
public void setAppId(int appId) {
this.appId = appId;
}
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getPSign() {
return pSign;
}
public void setPSign(String pSign) {
this.pSign = pSign;
}
public int getPlayerType() {
return mPlayerType;
}
public void setPlayerType(int mPlayerType) {
this.mPlayerType = mPlayerType;
}
public int getLiveType() {
return mLiveType;
}
public void setLiveType(int mLiveType) {
this.mLiveType = mLiveType;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(videoUrl);
dest.writeInt(appId);
dest.writeString(fileId);
dest.writeString(pSign);
dest.writeInt(mPlayerType);
dest.writeInt(mLiveType);
dest.writeString(mToken);
}
}
...@@ -6,8 +6,8 @@ import android.content.res.Resources; ...@@ -6,8 +6,8 @@ import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import com.tencent.liteav.base.util.LiteavLog;
import com.tencent.rtmp.downloader.TXVodDownloadMediaInfo; import com.tencent.rtmp.downloader.TXVodDownloadMediaInfo;
import com.tencent.vod.flutter.FTXEvent; import com.tencent.vod.flutter.FTXEvent;
import com.tencent.vod.flutter.messages.FtxMessages.BoolMsg; import com.tencent.vod.flutter.messages.FtxMessages.BoolMsg;
...@@ -68,7 +68,7 @@ public class TXCommonUtil { ...@@ -68,7 +68,7 @@ public class TXCommonUtil {
maxBrightness = system.getInteger(resId); maxBrightness = system.getInteger(resId);
} }
} catch (Exception e) { } catch (Exception e) {
Log.getStackTraceString(e); LiteavLog.e(TAG, "getBrightnessMax error", e);
} }
if (TXCommonUtil.isMIUI() && Build.VERSION.SDK_INT >= 33) { if (TXCommonUtil.isMIUI() && Build.VERSION.SDK_INT >= 33) {
maxBrightness = 128F; maxBrightness = 128F;
......
...@@ -7,19 +7,35 @@ import android.os.Bundle; ...@@ -7,19 +7,35 @@ import android.os.Bundle;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import io.flutter.Log; import com.tencent.liteav.base.util.LiteavLog;
import java.util.ArrayList;
import java.util.List;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
public class TXFlutterEngineHolder { public class TXFlutterEngineHolder {
private static final String TAG = "TXFlutterEngineHolder"; private static final String TAG = "TXFlutterEngineHolder";
private static final class SingletonInstance {
private static TXFlutterEngineHolder instance = new TXFlutterEngineHolder();
}
private int mFrontContextCount = 0; private int mFrontContextCount = 0;
private Application.ActivityLifecycleCallbacks mLifeCallback; private Application.ActivityLifecycleCallbacks mLifeCallback;
private final List<TXAppStatusListener> mListeners = new ArrayList<>();
private boolean mIsEnterBack = false;
private final List<Activity> mActivityList = new ArrayList<>();
public static TXFlutterEngineHolder getInstance() {
return SingletonInstance.instance;
}
public void attachBindLife(ActivityPluginBinding binding) { public void attachBindLife(ActivityPluginBinding binding) {
if (mLifeCallback != null) { if (mLifeCallback != null) {
Log.w(TAG, "TXFlutterEngineHolder is already attach"); LiteavLog.w(TAG, "TXFlutterEngineHolder is already attach");
return; return;
} }
if (null == binding) { if (null == binding) {
...@@ -32,6 +48,7 @@ public class TXFlutterEngineHolder { ...@@ -32,6 +48,7 @@ public class TXFlutterEngineHolder {
return; return;
} }
mLifeCallback = new Application.ActivityLifecycleCallbacks() { mLifeCallback = new Application.ActivityLifecycleCallbacks() {
@Override @Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
...@@ -40,11 +57,23 @@ public class TXFlutterEngineHolder { ...@@ -40,11 +57,23 @@ public class TXFlutterEngineHolder {
@Override @Override
public void onActivityStarted(@NonNull Activity activity) { public void onActivityStarted(@NonNull Activity activity) {
mFrontContextCount++; mFrontContextCount++;
if (mIsEnterBack && mFrontContextCount > 0) {
mIsEnterBack = false;
notifyResume();
}
} }
@Override @Override
public void onActivityResumed(@NonNull Activity activity) { public void onActivityResumed(@NonNull Activity activity) {
synchronized (mActivityList) {
if (mActivityList.contains(activity)) {
// refresh index
mActivityList.remove(activity);
mActivityList.add(activity);
} else {
mActivityList.add(activity);
}
}
} }
@Override @Override
...@@ -55,6 +84,10 @@ public class TXFlutterEngineHolder { ...@@ -55,6 +84,10 @@ public class TXFlutterEngineHolder {
@Override @Override
public void onActivityStopped(@NonNull Activity activity) { public void onActivityStopped(@NonNull Activity activity) {
mFrontContextCount--; mFrontContextCount--;
if (!mIsEnterBack && mFrontContextCount <= 0) {
mIsEnterBack = true;
notifyEnterBack();
}
} }
@Override @Override
...@@ -64,14 +97,33 @@ public class TXFlutterEngineHolder { ...@@ -64,14 +97,33 @@ public class TXFlutterEngineHolder {
@Override @Override
public void onActivityDestroyed(@NonNull Activity activity) { public void onActivityDestroyed(@NonNull Activity activity) {
synchronized (mActivityList) {
mActivityList.remove(activity);
}
} }
}; };
binding.getActivity().getApplication().registerActivityLifecycleCallbacks(mLifeCallback); binding.getActivity().getApplication().registerActivityLifecycleCallbacks(mLifeCallback);
} }
public boolean isInForeground() { public boolean isInForeground() {
return mFrontContextCount > 0; return !mIsEnterBack;
}
public Activity getActivityByIndex(int index) {
synchronized (mActivityList) {
if (index >= mActivityList.size() || index < 0) {
return null;
}
return mActivityList.get(index);
}
}
public Activity getPreActivity() {
synchronized (mActivityList) {
final int size = mActivityList.size();
final int preIndex = size - 2;
return getActivityByIndex(preIndex);
}
} }
public void destroy(ActivityPluginBinding binding) { public void destroy(ActivityPluginBinding binding) {
...@@ -89,4 +141,46 @@ public class TXFlutterEngineHolder { ...@@ -89,4 +141,46 @@ public class TXFlutterEngineHolder {
} }
binding.getActivity().getApplication().unregisterActivityLifecycleCallbacks(mLifeCallback); binding.getActivity().getApplication().unregisterActivityLifecycleCallbacks(mLifeCallback);
} }
public void addAppLifeListener(TXAppStatusListener listener) {
synchronized (mListeners) {
if (!mListeners.contains(listener)) {
mListeners.add(listener);
}
}
}
public void removeAppLifeListener(TXAppStatusListener listener) {
synchronized (mListeners) {
mListeners.remove(listener);
}
}
public void clearListener() {
synchronized (mListeners) {
mListeners.clear();
}
}
private void notifyResume() {
synchronized (mListeners) {
for (TXAppStatusListener listener : mListeners) {
listener.onResume();
}
}
}
private void notifyEnterBack() {
synchronized (mListeners) {
for (TXAppStatusListener listener : mListeners) {
listener.onEnterBack();
}
}
}
public abstract static class TXAppStatusListener {
public abstract void onResume();
public abstract void onEnterBack();
}
} }
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/transparent" android:background="@android:color/transparent"
tools:context="com.tencent.vod.flutter.ui.FlutterPipImplActivity"> tools:context="com.tencent.vod.flutter.ui.FlutterPipImplActivity">
<SurfaceView <SurfaceView
android:id="@+id/sv_video_container" android:id="@+id/sv_video_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:visibility="gone"/> android:visibility="gone" />
<ProgressBar <ProgressBar
android:id="@+id/pb_video_progress" android:id="@+id/pb_video_progress"
style="@android:style/Widget.Holo.ProgressBar.Horizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="3dp" android:layout_height="3dp"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:max="100" android:max="100"
android:visibility="gone" android:visibility="gone" />
style="@android:style/Widget.Holo.ProgressBar.Horizontal"/>
</RelativeLayout> </RelativeLayout>
\ No newline at end of file
...@@ -27,11 +27,12 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" ...@@ -27,11 +27,12 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
compileSdkVersion 33 compileSdkVersion 33
namespace="com.example.flutter.player"
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.tencent.liteav.demo" applicationId "com.tencent.liteav.demo"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 31 targetSdkVersion 33
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
} }
...@@ -44,7 +45,7 @@ android { ...@@ -44,7 +45,7 @@ android {
} }
debug { debug {
minifyEnabled true // 关闭混淆 minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
} }
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
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.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" />
......
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
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.
--> -->
......
...@@ -20,6 +20,8 @@ class _DemoShortVideoPlayerState extends State<DemoShortVideoPlayer> with Widget ...@@ -20,6 +20,8 @@ class _DemoShortVideoPlayerState extends State<DemoShortVideoPlayer> with Widget
@override @override
void initState() { void initState() {
super.initState(); super.initState();
// stop pip window if exists
TXPipController.instance.exitAndReleaseCurrentPip();
ShortVideoDataLoader loader = ShortVideoDataLoader(); ShortVideoDataLoader loader = ShortVideoDataLoader();
loader.getPageListDataOneByOneFunction((dataModels) { loader.getPageListDataOneByOneFunction((dataModels) {
setState(() { setState(() {
......
...@@ -118,7 +118,7 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -118,7 +118,7 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
), ),
), ),
), ),
onWillPop: onWillPop); onWillPop: onWillPop,);
} }
Future<bool> onWillPop() async { Future<bool> onWillPop() async {
...@@ -217,7 +217,9 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto ...@@ -217,7 +217,9 @@ class _DemoSuperPlayerState extends State<DemoSuperPlayer> with TXPipPlayerResto
onTap: () => playCurrentModel(playModel, 0), onTap: () => playCurrentModel(playModel, 0),
horizontalTitleGap: 10, horizontalTitleGap: 10,
), ),
Divider() Divider(
color: Colors.transparent,
)
], ],
); );
} }
......
...@@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; ...@@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:super_player/super_player.dart'; import 'package:super_player/super_player.dart';
import 'package:super_player_example/res/app_localizations.dart'; import 'package:super_player_example/res/app_localizations.dart';
import 'package:superplayer_widget/demo_superplayer_lib.dart';
import 'ui/demo_inputdialog.dart'; import 'ui/demo_inputdialog.dart';
import 'ui/demo_volume_slider.dart'; import 'ui/demo_volume_slider.dart';
...@@ -94,6 +95,8 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO ...@@ -94,6 +95,8 @@ class _DemoTXLivelayerState extends State<DemoTXLivePlayer> with WidgetsBindingO
@override @override
void initState() { void initState() {
super.initState(); super.initState();
// stop pip window if exists
TXPipController.instance.exitAndReleaseCurrentPip();
init(); init();
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
EasyLoading.show(status: 'loading...'); EasyLoading.show(status: 'loading...');
......
...@@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; ...@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'dart:async'; import 'dart:async';
import 'package:super_player/super_player.dart'; import 'package:super_player/super_player.dart';
import 'package:super_player_example/res/app_localizations.dart'; import 'package:super_player_example/res/app_localizations.dart';
import 'package:superplayer_widget/demo_superplayer_lib.dart';
import 'ui/demo_inputdialog.dart'; import 'ui/demo_inputdialog.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'ui/demo_volume_slider.dart'; import 'ui/demo_volume_slider.dart';
...@@ -102,6 +103,8 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer> with WidgetsBindingOb ...@@ -102,6 +103,8 @@ class _DemoTXVodPlayerState extends State<DemoTXVodPlayer> with WidgetsBindingOb
@override @override
void initState() { void initState() {
super.initState(); super.initState();
// stop pip window if exists
TXPipController.instance.exitAndReleaseCurrentPip();
_controller = TXVodPlayerController(); _controller = TXVodPlayerController();
init(); init();
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
......
...@@ -5,7 +5,7 @@ import 'package:super_player/super_player.dart'; ...@@ -5,7 +5,7 @@ import 'package:super_player/super_player.dart';
/// progress slider widget /// progress slider widget
class VideoSliderView extends StatefulWidget { class VideoSliderView extends StatefulWidget {
final ChangeNotifier _controller; final TXPlayerController _controller;
VideoSliderView(this._controller,Key key):super(key: key); VideoSliderView(this._controller,Key key):super(key: key);
......
...@@ -27,7 +27,7 @@ dependencies: ...@@ -27,7 +27,7 @@ dependencies:
path: ../ path: ../
superplayer_widget: superplayer_widget:
# 该路径根据superplayer_widget存放路径改变 # 该路径根据superplayer_widget存放路径改变
path: ../superplayer_widget path: ../../FlutterWidget/superplayer_widget
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#import <libkern/OSAtomic.h> #import <libkern/OSAtomic.h>
#import "FtxMessages.h" #import "FtxMessages.h"
#import "TXCommonUtil.h" #import "TXCommonUtil.h"
#import "FTXLog.h"
static const int uninitialized = -1; static const int uninitialized = -1;
...@@ -301,7 +302,7 @@ static const int uninitialized = -1; ...@@ -301,7 +302,7 @@ static const int uninitialized = -1;
- (void)onPlayEvent:(int)EvtID withParam:(NSDictionary *)param - (void)onPlayEvent:(int)EvtID withParam:(NSDictionary *)param
{ {
[_eventSink success:[FTXLivePlayer getParamsWithEvent:EvtID withParams:param]]; [_eventSink success:[FTXLivePlayer getParamsWithEvent:EvtID withParams:param]];
NSLog(@"onLivePlayEvent:%i,%@", EvtID, param[EVT_PLAY_DESCRIPTION]); FTXLOGI(@"onLivePlayEvent:%i,%@", EvtID, param[EVT_PLAY_DESCRIPTION])
} }
/** /**
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#import "FTXEvent.h" #import "FTXEvent.h"
#import "FtxMessages.h" #import "FtxMessages.h"
#import "TXCommonUtil.h" #import "TXCommonUtil.h"
#import "FTXLog.h"
static const int uninitialized = -1; static const int uninitialized = -1;
static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
...@@ -375,7 +376,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -375,7 +376,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
return data; return data;
} }
} else { } else {
NSLog(@"getImageSprite failed, time is null or initImageSprite not invoke"); FTXLOGE(@"getImageSprite failed, time is null or initImageSprite not invoke");
} }
return nil; return nil;
} }
...@@ -462,7 +463,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -462,7 +463,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
}); });
} }
if (EvtID != PLAY_EVT_PLAY_PROGRESS) { if (EvtID != PLAY_EVT_PLAY_PROGRESS) {
NSLog(@"onPlayEvent:%i,%@", EvtID, param[EVT_PLAY_DESCRIPTION]); FTXLOGI(@"onPlayEvent:%i,%@", EvtID, param[EVT_PLAY_DESCRIPTION]);
} }
[_eventSink success:[FTXVodPlayer getParamsWithEvent:EvtID withParams:param]]; [_eventSink success:[FTXVodPlayer getParamsWithEvent:EvtID withParams:param]];
} }
...@@ -786,7 +787,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003; ...@@ -786,7 +787,7 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
break; break;
} }
self.hasEnteredPipMode = NO; self.hasEnteredPipMode = NO;
NSLog(@"[onPlayer], pictureInPictureErrorDidOccur errorType= %ld", type); FTXLOGE(@"[onPlayer], pictureInPictureErrorDidOccur errorType= %ld", type);
if (self.delegate && [self.delegate respondsToSelector:@selector(onPlayerPipStateError:)]) { if (self.delegate && [self.delegate respondsToSelector:@selector(onPlayerPipStateError:)]) {
[self.delegate onPlayerPipStateError:type]; [self.delegate onPlayerPipStateError:type];
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#import "FtxMessages.h" #import "FtxMessages.h"
#import "FTXVodPlayerDispatcher.h" #import "FTXVodPlayerDispatcher.h"
#import "FTXLivePlayerDispatcher.h" #import "FTXLivePlayerDispatcher.h"
#import "FTXLog.h"
@interface SuperPlayerPlugin ()<FlutterStreamHandler,FTXVodPlayerDelegate,TXFlutterSuperPlayerPluginAPI,TXFlutterNativeAPI, ITXPlayersBridge, FlutterPlugin, TXLiveBaseDelegate> @interface SuperPlayerPlugin ()<FlutterStreamHandler,FTXVodPlayerDelegate,TXFlutterSuperPlayerPluginAPI,TXFlutterNativeAPI, ITXPlayersBridge, FlutterPlugin, TXLiveBaseDelegate>
...@@ -303,6 +304,7 @@ SuperPlayerPlugin* instance; ...@@ -303,6 +304,7 @@ SuperPlayerPlugin* instance;
- (void)setLogLevelLogLevel:(nonnull IntMsg *)logLevel error:(FlutterError * _Nullable __autoreleasing * _Nonnull)error { - (void)setLogLevelLogLevel:(nonnull IntMsg *)logLevel error:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
[TXLiveBase setLogLevel:logLevel.value.intValue]; [TXLiveBase setLogLevel:logLevel.value.intValue];
[FTXLog setLogLevel:logLevel.value.intValue];
} }
- (nullable BoolMsg *)startVideoOrientationServiceWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error { - (nullable BoolMsg *)startVideoOrientationServiceWithError:(FlutterError * _Nullable __autoreleasing * _Nonnull)error {
......
// Copyright (c) 2022 Tencent. All rights reserved.
#ifndef SUPERPLAYER_FLUTTER_IOS_CLASSES_TOOLS_FTXLOG_H_
#define SUPERPLAYER_FLUTTER_IOS_CLASSES_TOOLS_FTXLOG_H_
#import <Foundation/Foundation.h>
#import "FTXLiteAVSDKHeader.h"
NS_ASSUME_NONNULL_BEGIN
#define FTXLOGV(fmt, ...) \
[FTXLog logLevel:LOGLEVEL_VERBOSE \
file:__FILE__ \
line:__LINE__ \
function:__FUNCTION__ \
info:[NSString stringWithFormat:fmt, ##__VA_ARGS__]];
#define FTXLOGD(fmt, ...) \
[FTXLog logLevel:LOGLEVEL_DEBUG \
file:__FILE__ \
line:__LINE__ \
function:__FUNCTION__ \
info:[NSString stringWithFormat:fmt, ##__VA_ARGS__]];
#define FTXLOGI(fmt, ...) \
[FTXLog logLevel:LOGLEVEL_INFO \
file:__FILE__ \
line:__LINE__ \
function:__FUNCTION__ \
info:[NSString stringWithFormat:fmt, ##__VA_ARGS__]];
#define FTXLOGW(fmt, ...) \
[FTXLog logLevel:LOGLEVEL_WARN \
file:__FILE__ \
line:__LINE__ \
function:__FUNCTION__ \
info:[NSString stringWithFormat:fmt, ##__VA_ARGS__]];
#define FTXLOGE(fmt, ...) \
[FTXLog logLevel:LOGLEVEL_ERROR \
file:__FILE__ \
line:__LINE__ \
function:__FUNCTION__ \
info:[NSString stringWithFormat:fmt, ##__VA_ARGS__]];
@interface FTXLog : NSObject
/**
* 日志打印
* @param level 方法
* @param file 文件名
* @param line 行
* @param function 方法
* @param info 信息
*/
+ (void)logLevel:(TX_Enum_Type_LogLevel)level
file:(const char *)file
line:(int)line
function:(const char *)function
info:(NSString *)info;
+ (void)setLogLevel:(TX_Enum_Type_LogLevel)level;
@end
NS_ASSUME_NONNULL_END
#endif // SUPERPLAYER_FLUTTER_IOS_CLASSES_TOOLS_FTXLOG_H_
// Copyright (c) 2022 Tencent. All rights reserved.
#import "FTXLog.h"
extern void tpl_log(int level, const char *file, int line, const char *func, const char *format, ...);
static TX_Enum_Type_LogLevel currentLogLevel = LOGLEVEL_VERBOSE;
@implementation FTXLog
+ (void)setLogLevel:(TX_Enum_Type_LogLevel)level {
currentLogLevel = level;
}
+ (void)logLevel:(TX_Enum_Type_LogLevel)level file:(const char *)file line:(int)line function:(const char *)function info:(NSString *)info {
if (level >= currentLogLevel) {
NSString *finalInfoString = [NSString stringWithFormat:@"[FTXPlayerLog] %@", info];
const char *finalInfo = [finalInfoString UTF8String];
[self logL:level
file:file
line:line
function:function
info:finalInfo];
}
}
#pragma mark - private methods
//LOGLEVEL_VERBOSE = 0, // VERBOSE
//LOGLEVEL_DEBUG = 1, // DEBUG
//LOGLEVEL_INFO = 2, // INFO
//LOGLEVEL_WARN = 3, // WARNING
//LOGLEVEL_ERROR = 4, // ERROR
//LOGLEVEL_FATAL = 5, // FATAL
//LOGLEVEL_NULL = 6, // NONE
+ (void)logL:(TX_Enum_Type_LogLevel)level
file:(const char *)file
line:(int)line
function:(const char *)function
info:(const char *)info {
switch (level) {
case LOGLEVEL_VERBOSE:
{
tpl_log(0, file, line, function, info);
}
break;
case LOGLEVEL_DEBUG:
{
tpl_log(1, file, line, function, info);
}
break;
case LOGLEVEL_INFO:
{
tpl_log(2, file, line, function, info);
}
break;
case LOGLEVEL_WARN:
{
tpl_log(3, file, line, function, info);
}
break;
case LOGLEVEL_ERROR:
{
tpl_log(4, file, line, function, info);
}
break;
case LOGLEVEL_FATAL:
{
tpl_log(5, file, line, function, info);
}
break;
case LOGLEVEL_NULL:
{
tpl_log(6, file, line, function, info);
}
break;
default:
break;
}
}
@end
...@@ -173,6 +173,8 @@ abstract class TXVodPlayEvent { ...@@ -173,6 +173,8 @@ abstract class TXVodPlayEvent {
// Video SEI frame information, Player Premium version 11.6 starts to support // Video SEI frame information, Player Premium version 11.6 starts to support
// 视频 SEI 帧信息, 播放器高级版 11.6 版本开始支持 // 视频 SEI 帧信息, 播放器高级版 11.6 版本开始支持
static const VOD_PLAY_EVT_VIDEO_SEI = 2030; static const VOD_PLAY_EVT_VIDEO_SEI = 2030;
// video loop once complete
static const VOD_PLAY_EVT_LOOP_ONCE_COMPLETE = 6001;
// UTC time // UTC time
// UTC时间 // UTC时间
......
...@@ -180,6 +180,10 @@ class SuperPlayerController { ...@@ -180,6 +180,10 @@ class SuperPlayerController {
break; break;
case TXVodPlayEvent.PLAY_EVT_PLAY_END: case TXVodPlayEvent.PLAY_EVT_PLAY_END:
_updatePlayerState(SuperPlayerState.END); _updatePlayerState(SuperPlayerState.END);
// reset start time when end
if (startPos > 0) {
await setStartTime(0);
}
break; break;
case TXVodPlayEvent.PLAY_EVT_PLAY_PROGRESS: case TXVodPlayEvent.PLAY_EVT_PLAY_PROGRESS:
dynamic progress = event[TXVodPlayEvent.EVT_PLAY_PROGRESS]; dynamic progress = event[TXVodPlayEvent.EVT_PLAY_PROGRESS];
...@@ -207,11 +211,17 @@ class SuperPlayerController { ...@@ -207,11 +211,17 @@ class SuperPlayerController {
currentSubtitleData = new TXVodSubtitleData(subtitleDataStr, startPositionMs, durationMs, trackIndex); currentSubtitleData = new TXVodSubtitleData(subtitleDataStr, startPositionMs, durationMs, trackIndex);
_observer?.onSubtitleData(currentSubtitleData); _observer?.onSubtitleData(currentSubtitleData);
break; break;
case TXVodPlayEvent.VOD_PLAY_EVT_SELECT_TRACK_COMPLETE: { case TXVodPlayEvent.VOD_PLAY_EVT_SELECT_TRACK_COMPLETE:
int trackIndex = event[TXVodPlayEvent.EVT_KEY_SELECT_TRACK_INDEX]; int trackIndex = event[TXVodPlayEvent.EVT_KEY_SELECT_TRACK_INDEX];
int errorCode = event[TXVodPlayEvent.EVT_KEY_SELECT_TRACK_ERROR_CODE]; int errorCode = event[TXVodPlayEvent.EVT_KEY_SELECT_TRACK_ERROR_CODE];
LogUtils.d(TAG, "SELECT_TRACK_COMPLETE trackIndex: ${trackIndex}, errorCode: ${errorCode}"); LogUtils.d(TAG, "SELECT_TRACK_COMPLETE trackIndex: ${trackIndex}, errorCode: ${errorCode}");
break;
case TXVodPlayEvent.VOD_PLAY_EVT_LOOP_ONCE_COMPLETE:
// reset start time when once complete
if (startPos > 0) {
await setStartTime(0);
} }
break;
} }
}); });
_vodNetEventListener = _vodPlayerController.onPlayerNetStatusBroadcast.listen((event) { _vodNetEventListener = _vodPlayerController.onPlayerNetStatusBroadcast.listen((event) {
......
...@@ -54,6 +54,10 @@ class TXPipController { ...@@ -54,6 +54,10 @@ class TXPipController {
} 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;
/**
* if you do not intend to continue reusing this vod player.
* exitAndReleaseCurrentPip must be called, otherwise there may be a obj leak
*/
await exitAndReleaseCurrentPip(); await exitAndReleaseCurrentPip();
} else if (eventCode == TXVodPlayEvent.EVENT_IOS_PIP_MODE_RESTORE_UI) { } else if (eventCode == TXVodPlayEvent.EVENT_IOS_PIP_MODE_RESTORE_UI) {
_extParams[ARGUMENT_PIP_START_TIME] = event["playTime"]; _extParams[ARGUMENT_PIP_START_TIME] = event["playTime"];
......
...@@ -132,7 +132,8 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs ...@@ -132,7 +132,8 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs
_pipSubscription = _pipSubscription =
SuperPlayerPlugin.instance.onExtraEventBroadcast.listen((event) { SuperPlayerPlugin.instance.onExtraEventBroadcast.listen((event) {
int eventCode = event["event"]; int eventCode = event["event"];
if (eventCode == TXVodPlayEvent.EVENT_PIP_MODE_ALREADY_EXIT) { if (eventCode == TXVodPlayEvent.EVENT_PIP_MODE_ALREADY_EXIT
|| eventCode == TXVodPlayEvent.EVENT_IOS_PIP_MODE_RESTORE_UI) {
_isFloatingMode = false; _isFloatingMode = false;
_playController._updatePlayerUIStatus(_pipPreUiStatus); _playController._updatePlayerUIStatus(_pipPreUiStatus);
} else if (eventCode == TXVodPlayEvent.EVENT_PIP_MODE_REQUEST_START) { } else if (eventCode == TXVodPlayEvent.EVENT_PIP_MODE_REQUEST_START) {
...@@ -634,7 +635,7 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs ...@@ -634,7 +635,7 @@ class SuperPlayerViewState extends State<SuperPlayerView> with WidgetsBindingObs
} else if (result == TXVodPlayEvent.ERROR_PIP_ACTIVITY_DESTROYED) { } else if (result == TXVodPlayEvent.ERROR_PIP_ACTIVITY_DESTROYED) {
failedStr = "enterPip failed,because activity is destroyed"; failedStr = "enterPip failed,because activity is destroyed";
} else { } else {
failedStr = "enterPip failed,unkonw error"; failedStr = "enterPip failed,unkonw error:$result";
} }
LogUtils.e(TAG, failedStr); LogUtils.e(TAG, failedStr);
} }
......
...@@ -20,7 +20,7 @@ dependencies: ...@@ -20,7 +20,7 @@ dependencies:
# See https://dart.dev/tools/pub/dependencies#version-constraints # See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on # The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version. # the parent directory to use the current plugin's version.
path: ../ path: ../../Flutter
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论