Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
T
tx_player_fork
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蒋俊
tx_player_fork
Commits
22901bfd
提交
22901bfd
authored
11月 23, 2022
作者:
kongdywang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
pip optimize
上级
ba8d10e6
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
34 个修改的文件
包含
699 行增加
和
187 行删除
+699
-187
config.gradle
Flutter/android/config.gradle
+1
-1
AndroidManifest.xml
Flutter/android/src/main/AndroidManifest.xml
+27
-2
FTXEvent.java
...droid/src/main/java/com/tencent/vod/flutter/FTXEvent.java
+37
-1
FTXLivePlayer.java
.../src/main/java/com/tencent/vod/flutter/FTXLivePlayer.java
+27
-26
FTXPIPManager.java
.../src/main/java/com/tencent/vod/flutter/FTXPIPManager.java
+0
-0
FTXVodPlayer.java
...d/src/main/java/com/tencent/vod/flutter/FTXVodPlayer.java
+43
-48
SuperPlayerPlugin.java
.../main/java/com/tencent/vod/flutter/SuperPlayerPlugin.java
+2
-2
PipResult.java
...rc/main/java/com/tencent/vod/flutter/model/PipResult.java
+75
-0
VideoModel.java
...c/main/java/com/tencent/vod/flutter/model/VideoModel.java
+107
-0
FlutterPipImplActivity.java
...va/com/tencent/vod/flutter/ui/FlutterPipImplActivity.java
+0
-0
activity_flutter_pip_impl.xml
...android/src/main/res/layout/activity_flutter_pip_impl.xml
+28
-0
strings.xml
Flutter/android/src/main/res/values/strings.xml
+2
-0
styles.xml
Flutter/android/src/main/res/values/styles.xml
+25
-0
MainActivity.java
...n/java/com/example/super_player_example/MainActivity.java
+3
-1
project.pbxproj
Flutter/example/ios/Runner.xcodeproj/project.pbxproj
+4
-4
Info.plist
Flutter/example/ios/Runner/Info.plist
+2
-2
demo_superplayer.dart
Flutter/example/lib/demo_superplayer.dart
+73
-32
demo_txvodplayer.dart
Flutter/example/lib/demo_txvodplayer.dart
+3
-4
main.dart
Flutter/example/lib/main.dart
+30
-24
treePage.dart
Flutter/example/lib/ui/treePage.dart
+1
-1
FTXEvent.h
Flutter/ios/Classes/FTXEvent.h
+2
-0
FTXVodPlayer.h
Flutter/ios/Classes/FTXVodPlayer.h
+1
-1
FTXVodPlayer.m
Flutter/ios/Classes/FTXVodPlayer.m
+17
-5
SuperPlayerPlugin.m
Flutter/ios/Classes/SuperPlayerPlugin.m
+4
-4
superplayer_plugin.dart
Flutter/lib/Core/superplayer_plugin.dart
+1
-1
txliveplayer_controller.dart
Flutter/lib/Core/txliveplayer_controller.dart
+8
-14
txplayer_controller.dart
Flutter/lib/Core/txplayer_controller.dart
+3
-0
txplayer_define.dart
Flutter/lib/Core/txplayer_define.dart
+8
-0
txvodplayer_controller.dart
Flutter/lib/Core/txvodplayer_controller.dart
+9
-0
demo_superplayer_lib.dart
Flutter/superplayer_widget/lib/demo_superplayer_lib.dart
+2
-0
txpipplayer_data.dart
Flutter/superplayer_widget/lib/model/txpipplayer_data.dart
+13
-0
superplayer_controller.dart
Flutter/superplayer_widget/lib/superplayer_controller.dart
+37
-14
txpip_controller.dart
Flutter/superplayer_widget/lib/tools/txpip_controller.dart
+104
-0
superplayer_widget.dart
Flutter/superplayer_widget/lib/ui/superplayer_widget.dart
+0
-0
没有找到文件。
Flutter/android/config.gradle
浏览文件 @
22901bfd
rootProject
.
ext
{
rootProject
.
ext
{
compileSdkVersion
=
28
compileSdkVersion
=
31
buildToolsVersion
=
"28.0.3"
buildToolsVersion
=
"28.0.3"
supportSdkVersion
=
"26.0.1"
supportSdkVersion
=
"26.0.1"
minSdkVersion
=
19
minSdkVersion
=
19
...
...
Flutter/android/src/main/AndroidManifest.xml
浏览文件 @
22901bfd
<?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"
package=
"com.tencent.vod.flutterr"
>
xmlns:tools=
"http://schemas.android.com/tools"
</manifest>
package=
"com.tencent.vod.flutterr"
>
<application>
<activity
android:name=
"com.tencent.vod.flutter.ui.FlutterPipImplActivity"
android:theme=
"@style/Theme"
android:supportsPictureInPicture=
"true"
android:screenOrientation=
"portrait"
android:exported=
"true"
android:resizeableActivity=
"true"
android:launchMode=
"singleTop"
android:configChanges=
"orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated=
"true"
android:windowSoftInputMode=
"stateHidden"
tools:ignore=
"UnusedAttribute"
>
<intent-filter>
<action
android:name=
"com.tencent.flutter.startPip"
/>
<action
android:name=
"com.tencent.flutter.exitPip"
/>
<action
android:name=
"com.tencent.flutter.updatePip"
/>
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXEvent.java
浏览文件 @
22901bfd
...
@@ -35,10 +35,11 @@ public class FTXEvent {
...
@@ -35,10 +35,11 @@ public class FTXEvent {
// 视频下载错误
// 视频下载错误
public
static
final
int
EVENT_DOWNLOAD_ERROR
=
305
;
public
static
final
int
EVENT_DOWNLOAD_ERROR
=
305
;
public
static
final
int
NO_ERROR
=
0
;
public
static
final
int
NO_ERROR
=
0
;
/**
/**
* pip 事件
* pip 事件
*/
*/
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
final
static
String
ACTION_PIP_PLAY_CONTROL
=
"vodPlayControl"
;
// pip 操作
// pip 操作
...
@@ -57,6 +58,40 @@ public class FTXEvent {
...
@@ -57,6 +58,40 @@ public class FTXEvent {
public
static
final
int
ERROR_PIP_DENIED_PERMISSION
=
-
102
;
public
static
final
int
ERROR_PIP_DENIED_PERMISSION
=
-
102
;
// pip 错误,当前界面已销毁
// pip 错误,当前界面已销毁
public
static
final
int
ERROR_PIP_ACTIVITY_DESTROYED
=
-
103
;
public
static
final
int
ERROR_PIP_ACTIVITY_DESTROYED
=
-
103
;
// 来自画中画容器的事件,广播键值
public
static
final
String
EVENT_PIP_ACTION
=
"com.tencent.flutter.pipevent"
;
// 来自画中画容器的事件,事件键值
public
static
final
String
EVENT_PIP_MODE_NAME
=
"pipEventName"
;
// 画中画当前播放时间
public
static
final
String
EVENT_PIP_PLAY_TIME
=
"playTime"
;
// 来自画中画容器的事件,已经进入画中画
public
static
final
int
EVENT_PIP_MODE_ALREADY_ENTER
=
1
;
// 来自画中画容器的事件,已经退出画中画
public
static
final
int
EVENT_PIP_MODE_ALREADY_EXIT
=
2
;
// 来自画中画容器的事件,开始进入画中画
public
static
final
int
EVENT_PIP_MODE_REQUEST_START
=
3
;
// 来自画中画容器的事件,画中画UI发生变动,> android 31
public
static
final
int
EVENT_PIP_MODE_UI_STATE_CHANGED
=
4
;
// 画中画界面恢复,即点击放大按钮
public
static
final
int
EVENT_PIP_MODE_RESTORE_UI
=
5
;
// 启动画中画
public
static
final
String
PIP_ACTION_START
=
"com.tencent.flutter.startPip"
;
// 退出画中画
public
static
final
String
PIP_ACTION_EXIT
=
"com.tencent.flutter.exitPip"
;
// 更新画中画
public
static
final
String
PIP_ACTION_UPDATE
=
"com.tencent.flutter.updatePip"
;
// 画中画参数
public
static
final
String
EXTRA_NAME_PARAMS
=
"pipParams"
;
// 视频源
public
static
final
String
EXTRA_NAME_VIDEO
=
"videoModel"
;
// 画中画结束参数
public
static
final
String
EXTRA_NAME_RESULT
=
"pipResult"
;
// 点播播放器
public
static
final
int
PLAYER_VOD
=
1
;
// 直播播放器
public
static
final
int
PLAYER_LIVE
=
2
;
// 屏幕旋转事件
// 屏幕旋转事件
...
@@ -71,4 +106,5 @@ public class FTXEvent {
...
@@ -71,4 +106,5 @@ public class FTXEvent {
public
static
final
int
ORIENTATION_PORTRAIT_DOWN
=
413
;
public
static
final
int
ORIENTATION_PORTRAIT_DOWN
=
413
;
// 横屏,底部在左
// 横屏,底部在左
public
static
final
int
ORIENTATION_LANDSCAPE_LEFT
=
414
;
public
static
final
int
ORIENTATION_LANDSCAPE_LEFT
=
414
;
}
}
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXLivePlayer.java
浏览文件 @
22901bfd
...
@@ -6,22 +6,20 @@ import android.graphics.SurfaceTexture;
...
@@ -6,22 +6,20 @@ import android.graphics.SurfaceTexture;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.util.Log
;
import
android.util.Log
;
import
android.view.Surface
;
import
android.view.Surface
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.NonNull
;
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.vod.flutter.model.PipResult
;
import
java.util.Map
;
import
com.tencent.vod.flutter.model.VideoModel
;
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
;
import
io.flutter.plugin.common.MethodCall
;
import
io.flutter.plugin.common.MethodCall
;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.view.TextureRegistry
;
import
io.flutter.view.TextureRegistry
;
import
java.util.Map
;
/**
/**
* live player processor
* live player processor
...
@@ -50,27 +48,15 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
...
@@ -50,27 +48,15 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
private
final
FTXPIPManager
mPipManager
;
private
final
FTXPIPManager
mPipManager
;
private
FTXPIPManager
.
PipParams
mPipParams
;
private
FTXPIPManager
.
PipParams
mPipParams
;
private
VideoModel
mVideoModel
;
private
final
FTXPIPManager
.
PipCallback
pipCallback
=
new
FTXPIPManager
.
PipCallback
()
{
private
final
FTXPIPManager
.
PipCallback
pipCallback
=
new
FTXPIPManager
.
PipCallback
()
{
@Override
@Override
public
void
onPlayBack
()
{
public
void
onPipResult
(
PipResult
result
)
{
// pip not support playback
// 启动pip的时候,当前player已经暂停,pip退出之后,如果退出的时候pip还处于播放状态,那么当前player也置为播放状态
}
boolean
isPipPlaying
=
result
.
isPlaying
();
if
(
isPipPlaying
)
{
@Override
public
void
onResumeOrPlay
()
{
boolean
isPlaying
=
isPlaying
();
if
(
isPlaying
)
{
pause
();
}
else
{
resume
();
resume
();
}
}
// isPlaying取反,点击暂停/播放之后,播放状态会变化
mPipManager
.
updatePipActions
(!
isPlaying
,
mPipParams
);
}
@Override
public
void
onPlayForward
()
{
// pip not support forward
}
}
};
};
...
@@ -80,6 +66,8 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
...
@@ -80,6 +66,8 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
mFlutterPluginBinding
=
flutterPluginBinding
;
mFlutterPluginBinding
=
flutterPluginBinding
;
mActivity
=
activity
;
mActivity
=
activity
;
mPipManager
=
pipManager
;
mPipManager
=
pipManager
;
mVideoModel
=
new
VideoModel
();
mVideoModel
.
setPlayerType
(
FTXEvent
.
PLAYER_LIVE
);
mSurfaceTextureEntry
=
mFlutterPluginBinding
.
getTextureRegistry
().
createSurfaceTexture
();
mSurfaceTextureEntry
=
mFlutterPluginBinding
.
getTextureRegistry
().
createSurfaceTexture
();
mSurfaceTexture
=
mSurfaceTextureEntry
.
surfaceTexture
();
mSurfaceTexture
=
mSurfaceTextureEntry
.
surfaceTexture
();
...
@@ -245,11 +233,22 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
...
@@ -245,11 +233,22 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
String
playPauseAssetPath
=
call
.
argument
(
"pauseIcon"
);
String
playPauseAssetPath
=
call
.
argument
(
"pauseIcon"
);
String
playForwardAssetPath
=
call
.
argument
(
"forwardIcon"
);
String
playForwardAssetPath
=
call
.
argument
(
"forwardIcon"
);
mPipManager
.
addCallback
(
getPlayerId
(),
pipCallback
);
mPipManager
.
addCallback
(
getPlayerId
(),
pipCallback
);
mPipParams
=
new
FTXPIPManager
.
PipParams
(
playBackAssetPath
,
playResumeAssetPath
,
mPipParams
=
new
FTXPIPManager
.
PipParams
(
playPauseAssetPath
,
mPipManager
.
toAndroidPath
(
playBackAssetPath
),
playForwardAssetPath
,
getPlayerId
(),
false
,
false
,
true
);
mPipManager
.
toAndroidPath
(
playResumeAssetPath
),
int
pipResult
=
mPipManager
.
enterPip
(
isPlaying
(),
mPipParams
);
mPipManager
.
toAndroidPath
(
playPauseAssetPath
),
mPipManager
.
toAndroidPath
(
playForwardAssetPath
),
getPlayerId
(),
false
,
false
,
true
);
mPipParams
.
setIsPlaying
(
isPlaying
());
int
pipResult
=
mPipManager
.
enterPip
(
mPipParams
,
mVideoModel
);
// 启动成功之后,暂停当前界面视频
if
(
pipResult
==
FTXEvent
.
NO_ERROR
)
{
pause
();
}
result
.
success
(
pipResult
);
result
.
success
(
pipResult
);
}
else
if
(
call
.
method
.
equals
(
"exitPictureInPictureMode"
))
{
mPipManager
.
exitPip
();
result
.
success
(
null
);
}
else
if
(
call
.
method
.
equals
(
"setConfig"
))
{
}
else
if
(
call
.
method
.
equals
(
"setConfig"
))
{
Map
<
Object
,
Object
>
config
=
call
.
argument
(
"config"
);
Map
<
Object
,
Object
>
config
=
call
.
argument
(
"config"
);
setPlayConfig
(
config
);
setPlayConfig
(
config
);
...
@@ -272,6 +271,8 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
...
@@ -272,6 +271,8 @@ public class FTXLivePlayer extends FTXBasePlayer implements MethodChannel.Method
int
startLivePlay
(
String
url
,
int
type
)
{
int
startLivePlay
(
String
url
,
int
type
)
{
Log
.
d
(
TAG
,
"startLivePlay:"
);
Log
.
d
(
TAG
,
"startLivePlay:"
);
mVideoModel
.
setVideoUrl
(
url
);
mVideoModel
.
setLiveType
(
type
);
if
(
mLivePlayer
!=
null
)
{
if
(
mLivePlayer
!=
null
)
{
mLivePlayer
.
setSurface
(
mSurface
);
mLivePlayer
.
setSurface
(
mSurface
);
mLivePlayer
.
setPlayListener
(
this
);
mLivePlayer
.
setPlayListener
(
this
);
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXPIPManager.java
浏览文件 @
22901bfd
差异被折叠。
点击展开。
Flutter/android/src/main/java/com/tencent/vod/flutter/FTXVodPlayer.java
浏览文件 @
22901bfd
...
@@ -6,9 +6,7 @@ import android.graphics.SurfaceTexture;
...
@@ -6,9 +6,7 @@ import android.graphics.SurfaceTexture;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
android.text.TextUtils
;
import
android.text.TextUtils
;
import
android.view.Surface
;
import
android.view.Surface
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.NonNull
;
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
;
...
@@ -17,18 +15,18 @@ import com.tencent.rtmp.TXLivePlayer;
...
@@ -17,18 +15,18 @@ import com.tencent.rtmp.TXLivePlayer;
import
com.tencent.rtmp.TXPlayInfoParams
;
import
com.tencent.rtmp.TXPlayInfoParams
;
import
com.tencent.rtmp.TXVodPlayConfig
;
import
com.tencent.rtmp.TXVodPlayConfig
;
import
com.tencent.rtmp.TXVodPlayer
;
import
com.tencent.rtmp.TXVodPlayer
;
import
com.tencent.vod.flutter.model.PipResult
;
import
java.io.ByteArrayOutputStream
;
import
com.tencent.vod.flutter.model.VideoModel
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
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
;
import
io.flutter.plugin.common.MethodCall
;
import
io.flutter.plugin.common.MethodCall
;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.plugin.common.MethodChannel
;
import
io.flutter.view.TextureRegistry
;
import
io.flutter.view.TextureRegistry
;
import
java.io.ByteArrayOutputStream
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
/**
* vodPlayer plugin processor
* vodPlayer plugin processor
...
@@ -49,6 +47,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
...
@@ -49,6 +47,7 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
private
TXVodPlayer
mVodPlayer
;
private
TXVodPlayer
mVodPlayer
;
private
TXImageSprite
mTxImageSprite
;
private
TXImageSprite
mTxImageSprite
;
private
VideoModel
mVideoModel
;
private
static
final
int
Uninitialized
=
-
101
;
private
static
final
int
Uninitialized
=
-
101
;
private
TextureRegistry
.
SurfaceTextureEntry
mSurfaceTextureEntry
;
private
TextureRegistry
.
SurfaceTextureEntry
mSurfaceTextureEntry
;
...
@@ -59,40 +58,18 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
...
@@ -59,40 +58,18 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
private
FTXPIPManager
.
PipParams
mPipParams
;
private
FTXPIPManager
.
PipParams
mPipParams
;
private
final
FTXPIPManager
.
PipCallback
pipCallback
=
new
FTXPIPManager
.
PipCallback
()
{
private
final
FTXPIPManager
.
PipCallback
pipCallback
=
new
FTXPIPManager
.
PipCallback
()
{
@Override
@Override
public
void
onPlayBack
()
{
public
void
onPipResult
(
PipResult
result
)
{
boolean
isPlaying
=
isPlaying
();
float
playTime
=
result
.
getPlayTime
();
if
(
isPlaying
)
{
float
duration
=
mVodPlayer
.
getDuration
();
float
backPlayTime
=
getCurrentPlaybackTime
()
-
10
;
if
(
playTime
>
duration
)
{
if
(
backPlayTime
<
0
)
{
playTime
=
duration
;
backPlayTime
=
0
;
}
seek
(
backPlayTime
);
}
}
}
seek
(
playTime
);
// 启动pip的时候,当前player已经暂停,pip退出之后,如果退出的时候pip还处于播放状态,那么当前player也置为播放状态
@Override
boolean
isPipPlaying
=
result
.
isPlaying
();
public
void
onResumeOrPlay
()
{
if
(
isPipPlaying
)
{
boolean
isPlaying
=
isPlaying
();
if
(
isPlaying
)
{
pause
();
}
else
{
resume
();
resume
();
}
}
// isPlaying取反,点击暂停/播放之后,播放状态会变化
mPipManager
.
updatePipActions
(!
isPlaying
,
mPipParams
);
}
@Override
public
void
onPlayForward
()
{
boolean
isPlaying
=
isPlaying
();
if
(
isPlaying
)
{
float
forwardPlayTime
=
getCurrentPlaybackTime
()
+
10
;
float
duration
=
mVodPlayer
.
getDuration
();
if
(
forwardPlayTime
>
duration
)
{
forwardPlayTime
=
duration
;
}
seek
(
forwardPlayTime
);
}
}
}
};
};
...
@@ -100,6 +77,8 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
...
@@ -100,6 +77,8 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
super
();
super
();
mPipManager
=
pipManager
;
mPipManager
=
pipManager
;
mFlutterPluginBinding
=
flutterPluginBinding
;
mFlutterPluginBinding
=
flutterPluginBinding
;
mVideoModel
=
new
VideoModel
();
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
());
...
@@ -196,10 +175,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
...
@@ -196,10 +175,6 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
}
}
}
else
if
(
event
==
TXLiveConstants
.
PLAY_WARNING_HW_ACCELERATION_FAIL
)
{
}
else
if
(
event
==
TXLiveConstants
.
PLAY_WARNING_HW_ACCELERATION_FAIL
)
{
mHardwareDecodeFail
=
true
;
mHardwareDecodeFail
=
true
;
}
else
if
(
event
==
TXLiveConstants
.
PLAY_EVT_PLAY_END
)
{
if
(
null
!=
mPipManager
&&
mPipManager
.
isInPipMode
())
{
mPipManager
.
updatePipActions
(
false
,
mPipParams
);
}
}
}
mEventSink
.
success
(
CommonUtil
.
getParams
(
event
,
bundle
));
mEventSink
.
success
(
CommonUtil
.
getParams
(
event
,
bundle
));
}
}
...
@@ -355,11 +330,23 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
...
@@ -355,11 +330,23 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
String
playPauseAssetPath
=
call
.
argument
(
"pauseIcon"
);
String
playPauseAssetPath
=
call
.
argument
(
"pauseIcon"
);
String
playForwardAssetPath
=
call
.
argument
(
"forwardIcon"
);
String
playForwardAssetPath
=
call
.
argument
(
"forwardIcon"
);
mPipManager
.
addCallback
(
getPlayerId
(),
pipCallback
);
mPipManager
.
addCallback
(
getPlayerId
(),
pipCallback
);
mPipParams
=
new
FTXPIPManager
.
PipParams
(
playBackAssetPath
,
playResumeAssetPath
,
mPipParams
=
new
FTXPIPManager
.
PipParams
(
playPauseAssetPath
,
mPipManager
.
toAndroidPath
(
playBackAssetPath
),
playForwardAssetPath
,
getPlayerId
());
mPipManager
.
toAndroidPath
(
playResumeAssetPath
),
int
pipResult
=
mPipManager
.
enterPip
(
isPlaying
(),
mPipParams
);
mPipManager
.
toAndroidPath
(
playPauseAssetPath
),
mPipManager
.
toAndroidPath
(
playForwardAssetPath
),
getPlayerId
());
mPipParams
.
setIsPlaying
(
isPlaying
());
mPipParams
.
setCurrentPlayTime
(
getCurrentPlaybackTime
());
int
pipResult
=
mPipManager
.
enterPip
(
mPipParams
,
mVideoModel
);
// 启动成功之后,暂停当前界面视频
if
(
pipResult
==
FTXEvent
.
NO_ERROR
)
{
pause
();
}
result
.
success
(
pipResult
);
result
.
success
(
pipResult
);
}
else
if
(
call
.
method
.
equals
(
"exitPictureInPictureMode"
))
{
mPipManager
.
exitPip
();
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"
);
...
@@ -411,6 +398,10 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
...
@@ -411,6 +398,10 @@ 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
)
{
return
mVodPlayer
.
startVodPlay
(
url
);
return
mVodPlayer
.
startVodPlay
(
url
);
}
}
...
@@ -422,6 +413,10 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
...
@@ -422,6 +413,10 @@ public class FTXVodPlayer extends FTXBasePlayer implements MethodChannel.MethodC
int
appId
=
call
.
argument
(
"appId"
);
int
appId
=
call
.
argument
(
"appId"
);
String
fileId
=
call
.
argument
(
"fileId"
);
String
fileId
=
call
.
argument
(
"fileId"
);
String
psign
=
call
.
argument
(
"psign"
);
String
psign
=
call
.
argument
(
"psign"
);
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
);
}
}
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/SuperPlayerPlugin.java
浏览文件 @
22901bfd
...
@@ -246,7 +246,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
...
@@ -246,7 +246,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
private
void
initPipManagerIfNeed
()
{
private
void
initPipManagerIfNeed
()
{
if
(
null
==
mTxPipManager
)
{
if
(
null
==
mTxPipManager
)
{
mTxPipManager
=
new
FTXPIPManager
(
mTxAudioManager
,
m
ActivityPluginBinding
.
getActivity
()
,
mTxPipManager
=
new
FTXPIPManager
(
mTxAudioManager
,
m
FlutterPluginBinding
,
mActivityPluginBinding
,
mFlutterPluginBinding
.
getFlutterAssets
());
mFlutterPluginBinding
.
getFlutterAssets
());
}
}
}
}
...
@@ -280,7 +280,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
...
@@ -280,7 +280,7 @@ public class SuperPlayerPlugin implements FlutterPlugin, MethodCallHandler, Acti
@Override
@Override
public
void
onDetachedFromActivity
()
{
public
void
onDetachedFromActivity
()
{
if
(
null
!=
mTxPipManager
)
{
if
(
null
!=
mTxPipManager
)
{
mTxPipManager
.
release
Receiv
er
();
mTxPipManager
.
release
ActivityListen
er
();
}
}
unregisterReceiver
();
unregisterReceiver
();
}
}
...
...
Flutter/android/src/main/java/com/tencent/vod/flutter/model/PipResult.java
0 → 100644
浏览文件 @
22901bfd
package
com
.
tencent
.
vod
.
flutter
.
model
;
import
android.os.Parcel
;
import
android.os.Parcelable
;
public
class
PipResult
implements
Parcelable
{
private
Float
mPlayTime
;
private
boolean
mIsPlaying
;
private
int
mPlayerId
;
public
PipResult
(){}
protected
PipResult
(
Parcel
in
)
{
if
(
in
.
readByte
()
==
0
)
{
mPlayTime
=
null
;
}
else
{
mPlayTime
=
in
.
readFloat
();
}
mIsPlaying
=
in
.
readByte
()
!=
0
;
mPlayerId
=
in
.
readInt
();
}
public
static
final
Creator
<
PipResult
>
CREATOR
=
new
Creator
<
PipResult
>()
{
@Override
public
PipResult
createFromParcel
(
Parcel
in
)
{
return
new
PipResult
(
in
);
}
@Override
public
PipResult
[]
newArray
(
int
size
)
{
return
new
PipResult
[
size
];
}
};
public
Float
getPlayTime
()
{
return
mPlayTime
;
}
public
void
setPlayTime
(
Float
mPlayTime
)
{
this
.
mPlayTime
=
mPlayTime
;
}
public
boolean
isPlaying
()
{
return
mIsPlaying
;
}
public
void
setPlaying
(
boolean
playing
)
{
mIsPlaying
=
playing
;
}
public
int
getPlayerId
()
{
return
mPlayerId
;
}
public
void
setPlayerId
(
int
mPlayerId
)
{
this
.
mPlayerId
=
mPlayerId
;
}
@Override
public
int
describeContents
()
{
return
0
;
}
@Override
public
void
writeToParcel
(
Parcel
dest
,
int
flags
)
{
if
(
mPlayTime
==
null
)
{
dest
.
writeByte
((
byte
)
0
);
}
else
{
dest
.
writeByte
((
byte
)
1
);
dest
.
writeFloat
(
mPlayTime
);
}
dest
.
writeByte
((
byte
)
(
mIsPlaying
?
1
:
0
));
dest
.
writeInt
(
mPlayerId
);
}
}
Flutter/android/src/main/java/com/tencent/vod/flutter/model/VideoModel.java
0 → 100644
浏览文件 @
22901bfd
// 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
;
/**
* 视频model
*/
public
class
VideoModel
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
;
public
VideoModel
()
{}
protected
VideoModel
(
Parcel
in
)
{
videoUrl
=
in
.
readString
();
appId
=
in
.
readInt
();
fileId
=
in
.
readString
();
pSign
=
in
.
readString
();
mPlayerType
=
in
.
readInt
();
mLiveType
=
in
.
readInt
();
}
public
static
final
Creator
<
VideoModel
>
CREATOR
=
new
Creator
<
VideoModel
>()
{
@Override
public
VideoModel
createFromParcel
(
Parcel
in
)
{
return
new
VideoModel
(
in
);
}
@Override
public
VideoModel
[]
newArray
(
int
size
)
{
return
new
VideoModel
[
size
];
}
};
public
String
getVideoUrl
()
{
return
videoUrl
;
}
public
void
setVideoUrl
(
String
videoUrl
)
{
this
.
videoUrl
=
videoUrl
;
}
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
);
}
}
Flutter/android/src/main/java/com/tencent/vod/flutter/ui/FlutterPipImplActivity.java
0 → 100644
浏览文件 @
22901bfd
差异被折叠。
点击展开。
Flutter/android/src/main/res/layout/activity_flutter_pip_impl.xml
0 → 100644
浏览文件 @
22901bfd
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@android:color/transparent"
tools:context=
"com.tencent.vod.flutter.ui.FlutterPipImplActivity"
>
<SurfaceView
android:id=
"@+id/sv_video_container"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:visibility=
"gone"
/>
<ProgressBar
android:id=
"@+id/pb_video_progress"
android:layout_width=
"match_parent"
android:layout_height=
"3dp"
android:layout_alignParentBottom=
"true"
android:max=
"100"
android:visibility=
"gone"
style=
"@android:style/Widget.Holo.ProgressBar.Horizontal"
/>
</RelativeLayout>
\ No newline at end of file
Flutter/android/src/main/res/values/strings.xml
0 → 100644
浏览文件 @
22901bfd
<resources></resources>
\ No newline at end of file
Flutter/android/src/main/res/values/styles.xml
0 → 100644
浏览文件 @
22901bfd
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 取消界面转场动画使用-->
<style
name=
"Theme"
parent=
"android:Theme.Translucent.NoTitleBar.Fullscreen"
>
<item
name=
"android:windowAnimationStyle"
>
@style/Animation
</item>
<item
name=
"android:background"
>
@android:color/transparent
</item>
<item
name=
"android:windowIsTranslucent"
>
true
</item>
<item
name=
"android:windowBackground"
>
@android:color/transparent
</item>
</style>
<style
name=
"Animation"
>
<item
name=
"android:activityOpenEnterAnimation"
>
@null
</item>
<item
name=
"android:activityOpenExitAnimation"
>
@null
</item>
<item
name=
"android:activityCloseEnterAnimation"
>
@null
</item>
<item
name=
"android:activityCloseExitAnimation"
>
@null
</item>
<item
name=
"android:taskOpenEnterAnimation"
>
@null
</item>
<item
name=
"android:taskOpenExitAnimation"
>
@null
</item>
<item
name=
"android:taskCloseEnterAnimation"
>
@null
</item>
<item
name=
"android:taskCloseExitAnimation"
>
@null
</item>
<item
name=
"android:taskToFrontEnterAnimation"
>
@null
</item>
<item
name=
"android:taskToFrontExitAnimation"
>
@null
</item>
<item
name=
"android:taskToBackEnterAnimation"
>
@null
</item>
<item
name=
"android:taskToBackExitAnimation"
>
@null
</item>
</style>
</resources>
\ No newline at end of file
Flutter/example/android/app/src/main/java/com/example/super_player_example/MainActivity.java
浏览文件 @
22901bfd
// Copyright (c) 2022 Tencent. All rights reserved.
// Copyright (c) 2022 Tencent. All rights reserved.
package
com
.
example
.
super_player_example
;
package
com
.
example
.
super_player_example
;
public
class
MainActivity
extends
FTXFlutterPipActivity
{
import
io.flutter.embedding.android.FlutterActivity
;
public
class
MainActivity
extends
FlutterActivity
{
}
}
Flutter/example/ios/Runner.xcodeproj/project.pbxproj
浏览文件 @
22901bfd
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
archiveVersion
=
1
;
archiveVersion
=
1
;
classes
=
{
classes
=
{
};
};
objectVersion
=
5
0
;
objectVersion
=
5
1
;
objects
=
{
objects
=
{
/* Begin PBXBuildFile section */
/* Begin PBXBuildFile section */
...
@@ -393,7 +393,7 @@
...
@@ -393,7 +393,7 @@
"$(inherited)"
,
"$(inherited)"
,
"@executable_path/Frameworks"
,
"@executable_path/Frameworks"
,
);
);
PRODUCT_BUNDLE_IDENTIFIER
=
com.yunxiao.dev.liteavdemo
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.yunxiao.dev.liteav
.
demo
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
"Yunxiao Develop Profile"
;
PROVISIONING_PROFILE_SPECIFIER
=
"Yunxiao Develop Profile"
;
VERSIONING_SYSTEM
=
"apple-generic"
;
VERSIONING_SYSTEM
=
"apple-generic"
;
...
@@ -522,7 +522,7 @@
...
@@ -522,7 +522,7 @@
"$(inherited)"
,
"$(inherited)"
,
"@executable_path/Frameworks"
,
"@executable_path/Frameworks"
,
);
);
PRODUCT_BUNDLE_IDENTIFIER
=
com.yunxiao.dev.liteavdemo
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.yunxiao.dev.liteav
.
demo
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
"Yunxiao Develop Profile"
;
PROVISIONING_PROFILE_SPECIFIER
=
"Yunxiao Develop Profile"
;
VERSIONING_SYSTEM
=
"apple-generic"
;
VERSIONING_SYSTEM
=
"apple-generic"
;
...
@@ -544,7 +544,7 @@
...
@@ -544,7 +544,7 @@
"$(inherited)"
,
"$(inherited)"
,
"@executable_path/Frameworks"
,
"@executable_path/Frameworks"
,
);
);
PRODUCT_BUNDLE_IDENTIFIER
=
com.yunxiao.dev.liteavdemo
;
PRODUCT_BUNDLE_IDENTIFIER
=
com.yunxiao.dev.liteav
.
demo
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PRODUCT_NAME
=
"$(TARGET_NAME)"
;
PROVISIONING_PROFILE_SPECIFIER
=
"Yunxiao Develop Profile"
;
PROVISIONING_PROFILE_SPECIFIER
=
"Yunxiao Develop Profile"
;
VERSIONING_SYSTEM
=
"apple-generic"
;
VERSIONING_SYSTEM
=
"apple-generic"
;
...
...
Flutter/example/ios/Runner/Info.plist
浏览文件 @
22901bfd
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
<
!
D
O
C
TYP
E
plist
PU
B
LI
C
"-//
A
ppl
e
//
D
T
D
PLIST
1
.
0
//
E
N"
"http://www.
a
ppl
e
.
c
om/
D
T
D
s/Prop
e
rtyList-
1
.
0
.
d
t
d
"
>
<
!
D
O
C
TYP
E
plist
PU
B
LI
C
"-//
A
ppl
e
//
D
T
D
PLIST
1
.
0
//
E
N"
"http://www.
a
ppl
e
.
c
om/
D
T
D
s/Prop
e
rtyList-
1
.
0
.
d
t
d
"
>
<
plist
v
e
rsion="
1
.
0
"
>
<
plist
v
e
rsion="
1
.
0
"
>
<
d
i
c
t
>
<
d
i
c
t
>
<
k
e
y
>
CADisableMinimumFrameDurationOnPhone
<
/k
e
y
>
<
tru
e
/
>
<
k
e
y
>
CFBundleDevelopmentRegion
<
/k
e
y
>
<
k
e
y
>
CFBundleDevelopmentRegion
<
/k
e
y
>
<
string
>
$
(
DEVELOPMENT_LANGUAGE
)<
/string
>
<
string
>
$
(
DEVELOPMENT_LANGUAGE
)<
/string
>
<
k
e
y
>
CFBundleExecutable
<
/k
e
y
>
<
k
e
y
>
CFBundleExecutable
<
/k
e
y
>
...
@@ -52,7 +54,5 @@
...
@@ -52,7 +54,5 @@
<
fa
ls
e
/
>
<
fa
ls
e
/
>
<
k
e
y
>
io.flutter.embedded_views_preview
<
/k
e
y
>
<
k
e
y
>
io.flutter.embedded_views_preview
<
/k
e
y
>
<
tru
e
/
>
<
tru
e
/
>
<
k
e
y
>
CADisableMinimumFrameDurationOnPhone
<
/k
e
y
>
<
tru
e
/
>
<
/
d
i
c
t
>
<
/
d
i
c
t
>
<
/plist
>
<
/plist
>
Flutter/example/lib/demo_superplayer.dart
浏览文件 @
22901bfd
...
@@ -8,26 +8,31 @@ import 'package:super_player_example/ui/demo_inputdialog.dart';
...
@@ -8,26 +8,31 @@ import 'package:super_player_example/ui/demo_inputdialog.dart';
import
'package:superplayer_widget/demo_superplayer_lib.dart'
;
import
'package:superplayer_widget/demo_superplayer_lib.dart'
;
/// flutter superplayer demo
/// flutter superplayer demo
class
DemoSuperplayer
extends
StatefulWidget
{
class
DemoSuperPlayer
extends
StatefulWidget
{
Map
?
initParams
=
{};
DemoSuperPlayer
({
this
.
initParams
});
@override
@override
State
<
StatefulWidget
>
createState
()
=>
_DemoSuper
p
layerState
();
State
<
StatefulWidget
>
createState
()
=>
_DemoSuper
P
layerState
();
}
}
class
_DemoSuperplayerState
extends
State
<
DemoSuperplayer
>
{
class
_DemoSuperPlayerState
extends
State
<
DemoSuperPlayer
>
with
TXPipPlayerRestorePage
{
static
const
DEFAULT_PLACE_HOLDER
=
"http://xiaozhibo-10055601.file.myqcloud.com/coverImg.jpg"
;
static
const
DEFAULT_PLACE_HOLDER
=
"http://xiaozhibo-10055601.file.myqcloud.com/coverImg.jpg"
;
static
const
ARGUMENT_TYPE_POS
=
"arg_type_pos"
;
static
const
ARGUMENT_VIDEO_DATA
=
"arg_video_data"
;
List
<
SuperPlayerModel
>
videoModels
=
[];
List
<
SuperPlayerModel
>
videoModels
=
[];
bool
_isFullScreen
=
false
;
bool
_isFullScreen
=
false
;
late
SuperPlayerController
_controller
;
late
SuperPlayerController
_controller
;
StreamSubscription
?
simpleEventSubscription
;
StreamSubscription
?
simpleEventSubscription
;
int
tabSelectPos
=
0
;
int
tabSelectPos
=
0
;
TextStyle
_textStyleSelected
=
new
TextStyle
(
SuperPlayerModel
?
currentVideoModel
;
fontSize:
16
,
color:
Colors
.
white
SuperPlayerModel
?
initVideoModel
;
);
double
?
initStartTime
;
TextStyle
_textStyleUnSelected
=
new
TextStyle
(
TextStyle
_textStyleSelected
=
new
TextStyle
(
fontSize:
16
,
color:
Colors
.
white
);
fontSize:
16
,
color:
Colors
.
grey
TextStyle
_textStyleUnSelected
=
new
TextStyle
(
fontSize:
16
,
color:
Colors
.
grey
);
);
@override
@override
void
initState
()
{
void
initState
()
{
...
@@ -35,6 +40,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
...
@@ -35,6 +40,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
// 监听设备旋转
// 监听设备旋转
SuperPlayerPlugin
.
startVideoOrientationService
();
SuperPlayerPlugin
.
startVideoOrientationService
();
_controller
=
SuperPlayerController
(
context
);
_controller
=
SuperPlayerController
(
context
);
TXPipController
.
instance
.
setPipPlayerPage
(
DemoSuperPlayer
,
this
);
FTXVodPlayConfig
config
=
FTXVodPlayConfig
();
FTXVodPlayConfig
config
=
FTXVodPlayConfig
();
// 如果不配置preferredResolution,则在播放多码率视频的时候优先播放720 * 1280分辨率的码率
// 如果不配置preferredResolution,则在播放多码率视频的时候优先播放720 * 1280分辨率的码率
config
.
preferredResolution
=
720
*
1280
;
config
.
preferredResolution
=
720
*
1280
;
...
@@ -49,7 +55,16 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
...
@@ -49,7 +55,16 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
print
(
evtName
);
print
(
evtName
);
}
}
});
});
_getLiveListData
();
if
(
null
!=
widget
.
initParams
)
{
tabSelectPos
=
widget
.
initParams
![
ARGUMENT_TYPE_POS
];
initVideoModel
=
widget
.
initParams
![
ARGUMENT_VIDEO_DATA
];
initStartTime
=
widget
.
initParams
![
TXPipController
.
ARGUMENT_PIP_START_TIME
];
}
if
(
tabSelectPos
==
0
)
{
_getLiveListData
();
}
else
if
(
tabSelectPos
==
1
)
{
_getVodListData
();
}
}
}
@override
@override
...
@@ -157,7 +172,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
...
@@ -157,7 +172,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
playModel
.
title
,
playModel
.
title
,
style:
TextStyle
(
color:
Colors
.
white
),
style:
TextStyle
(
color:
Colors
.
white
),
),
),
onTap:
()
=>
playCurrentModel
(
playModel
),
onTap:
()
=>
playCurrentModel
(
playModel
,
0
),
horizontalTitleGap:
10
,
horizontalTitleGap:
10
,
),
),
Divider
()
Divider
()
...
@@ -177,31 +192,50 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
...
@@ -177,31 +192,50 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
showDialog
(
showDialog
(
context:
context
,
context:
context
,
builder:
(
context
)
{
builder:
(
context
)
{
return
DemoInputDialog
(
""
,
0
,
""
,
(
String
url
,
int
appId
,
String
fileId
,
String
pSign
)
{
return
DemoInputDialog
(
SuperPlayerModel
model
=
new
SuperPlayerModel
();
""
,
model
.
appId
=
appId
;
0
,
if
(
url
.
isNotEmpty
)
{
""
,
model
.
videoURL
=
url
;
(
String
url
,
int
appId
,
String
fileId
,
String
pSign
)
{
}
else
if
(
appId
!=
0
&&
fileId
.
isNotEmpty
)
{
SuperPlayerModel
model
=
new
SuperPlayerModel
();
model
.
videoId
=
new
SuperPlayerVideoId
();
model
.
appId
=
appId
;
model
.
videoId
!.
fileId
=
fileId
;
if
(
url
.
isNotEmpty
)
{
if
(
pSign
.
isNotEmpty
)
{
model
.
videoURL
=
url
;
model
.
videoId
!.
psign
=
pSign
;
}
else
if
(
appId
!=
0
&&
fileId
.
isNotEmpty
)
{
model
.
videoId
=
new
SuperPlayerVideoId
();
model
.
videoId
!.
fileId
=
fileId
;
if
(
pSign
.
isNotEmpty
)
{
model
.
videoId
!.
psign
=
pSign
;
}
}
else
{
EasyLoading
.
showError
(
"请输入播放地址!"
);
return
;
}
}
}
else
{
EasyLoading
.
showError
(
"请输入播放地址!"
);
return
;
}
playCurrentModel
(
model
);
playCurrentModel
(
model
,
0
);
},
needPisgn:
!
isLive
,
showFileEdited:
!
isLive
,);
},
needPisgn:
!
isLive
,
showFileEdited:
!
isLive
,
);
});
});
}
}
void
playCurrentModel
(
SuperPlayerModel
model
)
{
void
playCurrentModel
(
SuperPlayerModel
model
,
double
startTime
)
{
currentVideoModel
=
model
;
_controller
.
setStartTime
(
startTime
);
_controller
.
playWithModelNeedLicence
(
model
);
_controller
.
playWithModelNeedLicence
(
model
);
}
}
void
playVideo
(
SuperPlayerModel
model
)
{
if
(
null
!=
initVideoModel
)
{
playCurrentModel
(
initVideoModel
!,
initStartTime
??
0
);
initVideoModel
=
null
;
initStartTime
=
null
;
}
else
{
playCurrentModel
(
model
,
0
);
}
}
void
_getLiveListData
()
async
{
void
_getLiveListData
()
async
{
setState
(()
{
setState
(()
{
tabSelectPos
=
0
;
tabSelectPos
=
0
;
...
@@ -212,7 +246,8 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
...
@@ -212,7 +246,8 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
SuperPlayerModel
model
=
SuperPlayerModel
();
SuperPlayerModel
model
=
SuperPlayerModel
();
model
.
title
=
"测试视频"
;
model
.
title
=
"测试视频"
;
model
.
videoURL
=
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo1080p.flv"
;
model
.
videoURL
=
"http://liteavapp.qcloud.com/live/liteavdemoplayerstreamid_demo1080p.flv"
;
model
.
coverUrl
=
"http://1500005830.vod2.myqcloud.com/6c9a5118vodcq1500005830/66bc542f387702300661648850/0RyP1rZfkdQA.png"
;
model
.
coverUrl
=
"http://1500005830.vod2.myqcloud.com/6c9a5118vodcq1500005830/66bc542f387702300661648850/0RyP1rZfkdQA.png"
;
model
.
playAction
=
playAction
;
model
.
playAction
=
playAction
;
models
.
add
(
model
);
models
.
add
(
model
);
...
@@ -220,7 +255,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
...
@@ -220,7 +255,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
videoModels
.
addAll
(
models
);
videoModels
.
addAll
(
models
);
setState
(()
{
setState
(()
{
if
(
videoModels
.
isNotEmpty
)
{
if
(
videoModels
.
isNotEmpty
)
{
play
CurrentModel
(
videoModels
[
0
]);
play
Video
(
videoModels
[
0
]);
}
else
{
}
else
{
EasyLoading
.
showError
(
"video list request error"
);
EasyLoading
.
showError
(
"video list request error"
);
}
}
...
@@ -290,7 +325,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
...
@@ -290,7 +325,7 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
videoModels
.
addAll
(
models
);
videoModels
.
addAll
(
models
);
setState
(()
{
setState
(()
{
if
(
videoModels
.
isNotEmpty
)
{
if
(
videoModels
.
isNotEmpty
)
{
play
CurrentModel
(
videoModels
[
0
]);
play
Video
(
videoModels
[
0
]);
}
else
{
}
else
{
EasyLoading
.
showError
(
"video list request error"
);
EasyLoading
.
showError
(
"video list request error"
);
}
}
...
@@ -306,4 +341,10 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
...
@@ -306,4 +341,10 @@ class _DemoSuperplayerState extends State<DemoSuperplayer> {
SuperPlayerPlugin
.
restorePageBrightness
();
SuperPlayerPlugin
.
restorePageBrightness
();
super
.
dispose
();
super
.
dispose
();
}
}
@override
void
onNeedSavePipPageState
(
Map
<
String
,
dynamic
>
params
)
{
params
[
ARGUMENT_TYPE_POS
]
=
tabSelectPos
;
params
[
ARGUMENT_VIDEO_DATA
]
=
currentVideoModel
;
}
}
}
Flutter/example/lib/demo_txvodplayer.dart
浏览文件 @
22901bfd
...
@@ -12,10 +12,10 @@ import 'ui/demo_video_slider_view.dart';
...
@@ -12,10 +12,10 @@ import 'ui/demo_video_slider_view.dart';
class
DemoTXVodPlayer
extends
StatefulWidget
{
class
DemoTXVodPlayer
extends
StatefulWidget
{
@override
@override
_DemoTXVod
layerState
createState
()
=>
_DemoTXVod
layerState
();
_DemoTXVod
PlayerState
createState
()
=>
_DemoTXVodP
layerState
();
}
}
class
_DemoTXVodlayerState
extends
State
<
DemoTXVodPlayer
>
class
_DemoTXVod
P
layerState
extends
State
<
DemoTXVodPlayer
>
with
WidgetsBindingObserver
{
with
WidgetsBindingObserver
{
late
TXVodPlayerController
_controller
;
late
TXVodPlayerController
_controller
;
double
_aspectRatio
=
16
/
9
;
double
_aspectRatio
=
16
/
9
;
...
@@ -24,8 +24,7 @@ class _DemoTXVodlayerState extends State<DemoTXVodPlayer>
...
@@ -24,8 +24,7 @@ class _DemoTXVodlayerState extends State<DemoTXVodPlayer>
int
_volume
=
100
;
int
_volume
=
100
;
List
_supportedBitrates
=
[];
List
_supportedBitrates
=
[];
int
_curBitrateIndex
=
0
;
int
_curBitrateIndex
=
0
;
String
_url
=
String
_url
=
"http://1400329073.vod2.myqcloud.com/d62d88a7vodtranscq1400329073/59c68fe75285890800381567412/adp.10.m3u8"
;
"http://1400329073.vod2.myqcloud.com/d62d88a7vodtranscq1400329073/59c68fe75285890800381567412/adp.10.m3u8"
;
int
_appId
=
0
;
int
_appId
=
0
;
String
_fileId
=
""
;
String
_fileId
=
""
;
double
_rate
=
1.0
;
double
_rate
=
1.0
;
...
...
Flutter/example/lib/main.dart
浏览文件 @
22901bfd
...
@@ -5,7 +5,9 @@ import 'package:flutter/material.dart';
...
@@ -5,7 +5,9 @@ import 'package:flutter/material.dart';
import
'package:flutter/services.dart'
;
import
'package:flutter/services.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/demo_superplayer.dart'
;
import
'package:super_player_example/shortvideo/demo_short_video_lib.dart'
;
import
'package:super_player_example/shortvideo/demo_short_video_lib.dart'
;
import
'package:superplayer_widget/demo_superplayer_lib.dart'
;
import
'ui/treePage.dart'
;
import
'ui/treePage.dart'
;
...
@@ -22,6 +24,7 @@ class MyApp extends StatefulWidget {
...
@@ -22,6 +24,7 @@ class MyApp extends StatefulWidget {
class
_MyAppState
extends
State
<
MyApp
>
{
class
_MyAppState
extends
State
<
MyApp
>
{
String
_platformVersion
=
'Unknown'
;
String
_platformVersion
=
'Unknown'
;
String
?
_liteAVSdkVersion
=
'Unknown'
;
String
?
_liteAVSdkVersion
=
'Unknown'
;
GlobalKey
<
NavigatorState
>
navigatorKey
=
GlobalKey
<
NavigatorState
>();
@override
@override
void
initState
()
{
void
initState
()
{
...
@@ -58,6 +61,9 @@ class _MyAppState extends State<MyApp> {
...
@@ -58,6 +61,9 @@ class _MyAppState extends State<MyApp> {
setState
(()
{
setState
(()
{
_platformVersion
=
platformVersion
!;
_platformVersion
=
platformVersion
!;
});
});
TXPipController
.
instance
.
setNavigatorHandle
((
params
)
{
navigatorKey
.
currentState
?.
push
(
MaterialPageRoute
(
builder:
(
_
)
=>
DemoSuperPlayer
(
initParams:
params
)));
});
}
}
Future
<
void
>
_getflutterSdkVersion
()
async
{
Future
<
void
>
_getflutterSdkVersion
()
async
{
...
@@ -70,38 +76,38 @@ class _MyAppState extends State<MyApp> {
...
@@ -70,38 +76,38 @@ class _MyAppState extends State<MyApp> {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
MaterialApp
(
return
MaterialApp
(
navigatorKey:
navigatorKey
,
home:
Container
(
home:
Container
(
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
image:
DecorationImage
(
image:
DecorationImage
(
image:
AssetImage
(
"images/ic_new_vod_bg.png"
),
image:
AssetImage
(
"images/ic_new_vod_bg.png"
),
fit:
BoxFit
.
cover
,
fit:
BoxFit
.
cover
,
)
)),
),
child:
Scaffold
(
child:
Scaffold
(
backgroundColor:
Colors
.
transparent
,
backgroundColor:
Colors
.
transparent
,
appBar:
AppBar
(
appBar:
AppBar
(
backgroundColor:
Colors
.
transparent
,
backgroundColor:
Colors
.
transparent
,
title:
const
Text
(
'腾讯云Flutter播放器'
,
style:
TextStyle
(
fontSize:
24
,
fontWeight:
FontWeight
.
w400
),),
title:
const
Text
(
),
'腾讯云Flutter播放器'
,
body:
Builder
(
style:
TextStyle
(
fontSize:
24
,
fontWeight:
FontWeight
.
w400
),
builder:
(
context
)
{
),
return
Container
(
color:
Colors
.
transparent
,
child:
Stack
(
children:
[
TreePage
(),
Align
(
alignment:
Alignment
.
bottomCenter
,
child:
Padding
(
padding:
new
EdgeInsets
.
all
(
20.0
)
,
child:
Text
(
'LiteAVSDKVersion:
${_liteAVSdkVersion}
'
),
)
),
],
),
);
}
),
),
body:
Builder
(
builder:
(
context
)
{
return
Container
(
color:
Colors
.
transparent
,
child:
Stack
(
children:
[
TreePage
(),
Align
(
alignment:
Alignment
.
bottomCenter
,
child:
Padding
(
padding:
new
EdgeInsets
.
all
(
20.0
),
child:
Text
(
'LiteAVSDKVersion:
${_liteAVSdkVersion}
'
),
)),
],
),
);
}),
),
),
),
),
builder:
EasyLoading
.
init
(),
builder:
EasyLoading
.
init
(),
...
...
Flutter/example/lib/ui/treePage.dart
浏览文件 @
22901bfd
...
@@ -136,7 +136,7 @@ class _TreePageState extends State<TreePage> {
...
@@ -136,7 +136,7 @@ class _TreePageState extends State<TreePage> {
}
else
if
(
i
==
1
)
{
}
else
if
(
i
==
1
)
{
return
DemoTXVodPlayer
();
return
DemoTXVodPlayer
();
}
else
if
(
i
==
2
){
}
else
if
(
i
==
2
){
return
DemoSuper
p
layer
();
return
DemoSuper
P
layer
();
}
else
{
}
else
{
return
DemoShortVideoPlayer
();
return
DemoShortVideoPlayer
();
}
}
...
...
Flutter/ios/Classes/FTXEvent.h
浏览文件 @
22901bfd
...
@@ -15,6 +15,8 @@
...
@@ -15,6 +15,8 @@
#define EVENT_PIP_MODE_RESTORE_UI 5
#define EVENT_PIP_MODE_RESTORE_UI 5
#define EVENT_PIP_MODE_WILL_EXIT 6
#define EVENT_PIP_MODE_WILL_EXIT 6
#define EVENT_PIP_PLAY_TIME @"playTime"
// 画中画错误事件code
// 画中画错误事件code
#define NO_ERROR 0 ///< 无错误
#define NO_ERROR 0 ///< 无错误
#define ERROR_IOS_PIP_DEVICE_NOT_SUPPORT -104 ///< 设备或系统版本不支持(iPad iOS9+ 才支持PIP)
#define ERROR_IOS_PIP_DEVICE_NOT_SUPPORT -104 ///< 设备或系统版本不支持(iPad iOS9+ 才支持PIP)
...
...
Flutter/ios/Classes/FTXVodPlayer.h
浏览文件 @
22901bfd
...
@@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
...
@@ -17,7 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
-
(
void
)
onPlayerPipStateDidStop
;
-
(
void
)
onPlayerPipStateDidStop
;
-
(
void
)
onPlayerPipStateRestoreUI
;
-
(
void
)
onPlayerPipStateRestoreUI
:(
double
)
playTime
;
;
-
(
void
)
onPlayerPipStateError
:(
NSInteger
)
errorId
;
-
(
void
)
onPlayerPipStateError
:(
NSInteger
)
errorId
;
...
...
Flutter/ios/Classes/FTXVodPlayer.m
浏览文件 @
22901bfd
...
@@ -39,6 +39,8 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
...
@@ -39,6 +39,8 @@ static const int CODE_ON_RECEIVE_FIRST_FRAME = 2003;
id
<
FlutterPluginRegistrar
>
_registrar
;
id
<
FlutterPluginRegistrar
>
_registrar
;
id
<
FlutterTextureRegistry
>
_textureRegistry
;
id
<
FlutterTextureRegistry
>
_textureRegistry
;
float
currentPlayTime
;
}
}
...
@@ -417,7 +419,7 @@ BOOL volatile isStop = false;
...
@@ -417,7 +419,7 @@ BOOL volatile isStop = false;
result
(
@
(
index
));
result
(
@
(
index
));
}
}
else
if
([
@"getPlayableDuration"
isEqualToString
:
call
.
method
]){
else
if
([
@"getPlayableDuration"
isEqualToString
:
call
.
method
]){
float
time
=
[
self
get
CurrentPlaybackTime
];
float
time
=
[
self
get
PlayableDuration
];
result
(
@
(
time
));
result
(
@
(
time
));
}
}
else
if
([
@"getDuration"
isEqualToString
:
call
.
method
]){
else
if
([
@"getDuration"
isEqualToString
:
call
.
method
]){
...
@@ -454,6 +456,12 @@ BOOL volatile isStop = false;
...
@@ -454,6 +456,12 @@ BOOL volatile isStop = false;
result
(
nil
);
result
(
nil
);
}
}
}
}
else
if
([
@"exitPictureInPictureMode"
isEqualToString
:
call
.
method
])
{
if
(
_txVodPlayer
!=
nil
)
{
[
_txVodPlayer
exitPictureInPicture
];
}
result
(
nil
);
}
else
{
else
{
result
(
FlutterMethodNotImplemented
);
result
(
FlutterMethodNotImplemented
);
}
}
...
@@ -522,7 +530,12 @@ BOOL volatile isStop = false;
...
@@ -522,7 +530,12 @@ BOOL volatile isStop = false;
{
{
// 交给flutter共享纹理处理首帧事件返回时机
// 交给flutter共享纹理处理首帧事件返回时机
if
(
EvtID
==
CODE_ON_RECEIVE_FIRST_FRAME
)
{
if
(
EvtID
==
CODE_ON_RECEIVE_FIRST_FRAME
)
{
currentPlayTime
=
0
;
return
;
return
;
}
else
if
(
EvtID
==
PLAY_EVT_PLAY_PROGRESS
)
{
currentPlayTime
=
[
param
[
EVT_PLAY_PROGRESS
]
floatValue
];
}
else
if
(
EvtID
==
PLAY_EVT_PLAY_BEGIN
)
{
currentPlayTime
=
0
;
}
}
[
_eventSink
success
:[
FTXVodPlayer
getParamsWithEvent
:
EvtID
withParams
:
param
]];
[
_eventSink
success
:[
FTXVodPlayer
getParamsWithEvent
:
EvtID
withParams
:
param
]];
...
@@ -769,14 +782,13 @@ BOOL volatile isStop = false;
...
@@ -769,14 +782,13 @@ BOOL volatile isStop = false;
if
(
pipState
==
TX_VOD_PLAYER_PIP_STATE_RESTORE_UI
)
{
if
(
pipState
==
TX_VOD_PLAYER_PIP_STATE_RESTORE_UI
)
{
self
.
restoreUI
=
YES
;
self
.
restoreUI
=
YES
;
if
(
self
.
delegate
&&
[
self
.
delegate
respondsToSelector
:
@selector
(
onPlayerPipStateRestoreUI
)])
{
[
self
.
delegate
onPlayerPipStateRestoreUI
];
}
dispatch_async
(
dispatch_get_main_queue
(),
^
{
dispatch_async
(
dispatch_get_main_queue
(),
^
{
[
player
exitPictureInPicture
];
[
player
exitPictureInPicture
];
[
self
->
_txVodPlayer
resume
];
[
self
->
_txVodPlayer
resume
];
});
});
if
(
self
.
delegate
&&
[
self
.
delegate
respondsToSelector
:
@selector
(
onPlayerPipStateRestoreUI
:)])
{
[
self
.
delegate
onPlayerPipStateRestoreUI
:
currentPlayTime
];
}
}
}
}
}
...
...
Flutter/ios/Classes/SuperPlayerPlugin.m
浏览文件 @
22901bfd
...
@@ -63,7 +63,7 @@ SuperPlayerPlugin* instance;
...
@@ -63,7 +63,7 @@ SuperPlayerPlugin* instance;
_eventSink
=
[
FTXPlayerEventSinkQueue
new
];
_eventSink
=
[
FTXPlayerEventSinkQueue
new
];
_pipEventSink
=
[
FTXPlayerEventSinkQueue
new
];
_pipEventSink
=
[
FTXPlayerEventSinkQueue
new
];
_eventChannel
=
[
FlutterEventChannel
eventChannelWithName
:
@"cloud.tencent.com/playerPlugin/event"
binaryMessenger
:[
registrar
messenger
]];
_eventChannel
=
[
FlutterEventChannel
eventChannelWithName
:
@"cloud.tencent.com/playerPlugin/event"
binaryMessenger
:[
registrar
messenger
]];
_pipEventChannel
=
[
FlutterEventChannel
eventChannelWithName
:
@"cloud.tencent.com/playerPlugin/
pip
Event"
binaryMessenger
:[
registrar
messenger
]];
_pipEventChannel
=
[
FlutterEventChannel
eventChannelWithName
:
@"cloud.tencent.com/playerPlugin/
component
Event"
binaryMessenger
:[
registrar
messenger
]];
[
_eventChannel
setStreamHandler
:
self
];
[
_eventChannel
setStreamHandler
:
self
];
[
_pipEventChannel
setStreamHandler
:
self
];
[
_pipEventChannel
setStreamHandler
:
self
];
...
@@ -194,7 +194,7 @@ SuperPlayerPlugin* instance;
...
@@ -194,7 +194,7 @@ SuperPlayerPlugin* instance;
result
(
@
(
setResult
));
result
(
@
(
setResult
));
}
else
if
([
@"startVideoOrientationService"
isEqualToString
:
call
.
method
])
{
}
else
if
([
@"startVideoOrientationService"
isEqualToString
:
call
.
method
])
{
// only for android
// only for android
result
(
@
(
true
));
result
(
@
(
YES
));
}
else
{
}
else
{
result
(
FlutterMethodNotImplemented
);
result
(
FlutterMethodNotImplemented
);
}
}
...
@@ -263,8 +263,8 @@ SuperPlayerPlugin* instance;
...
@@ -263,8 +263,8 @@ SuperPlayerPlugin* instance;
[
_pipEventSink
success
:@{
@"event"
:
@
(
errorId
)}];
[
_pipEventSink
success
:@{
@"event"
:
@
(
errorId
)}];
}
}
-
(
void
)
onPlayerPipStateRestoreUI
{
-
(
void
)
onPlayerPipStateRestoreUI
:
(
double
)
playTime
{
[
_pipEventSink
success
:@{
@"event"
:
@
(
EVENT_PIP_MODE_RESTORE_UI
)}];
[
_pipEventSink
success
:@{
@"event"
:
@
(
EVENT_PIP_MODE_RESTORE_UI
)
,
EVENT_PIP_PLAY_TIME
:
@
(
playTime
)
}];
}
}
#pragma mark - orientation
#pragma mark - orientation
...
...
Flutter/lib/Core/superplayer_plugin.dart
浏览文件 @
22901bfd
...
@@ -28,7 +28,7 @@ class SuperPlayerPlugin {
...
@@ -28,7 +28,7 @@ class SuperPlayerPlugin {
EventChannel
eventChannel
=
EventChannel
(
"cloud.tencent.com/playerPlugin/event"
);
EventChannel
eventChannel
=
EventChannel
(
"cloud.tencent.com/playerPlugin/event"
);
eventChannel
.
receiveBroadcastStream
(
"event"
).
listen
(
_eventHandler
,
onError:
_errorHandler
);
eventChannel
.
receiveBroadcastStream
(
"event"
).
listen
(
_eventHandler
,
onError:
_errorHandler
);
EventChannel
pipEventChanne
=
EventChannel
(
"cloud.tencent.com/playerPlugin/
pip
Event"
);
EventChannel
pipEventChanne
=
EventChannel
(
"cloud.tencent.com/playerPlugin/
component
Event"
);
pipEventChanne
.
receiveBroadcastStream
(
"pipEvent"
).
listen
(
_pipEventHandler
,
onError:
_errorHandler
);
pipEventChanne
.
receiveBroadcastStream
(
"pipEvent"
).
listen
(
_pipEventHandler
,
onError:
_errorHandler
);
}
}
...
...
Flutter/lib/Core/txliveplayer_controller.dart
浏览文件 @
22901bfd
...
@@ -311,20 +311,14 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
...
@@ -311,20 +311,14 @@ class TXLivePlayerController extends ChangeNotifier implements ValueListenable<T
String
?
playIconForAndroid
,
String
?
playIconForAndroid
,
String
?
pauseIconForAndroid
,
String
?
pauseIconForAndroid
,
String
?
forwardIconForAndroid
})
async
{
String
?
forwardIconForAndroid
})
async
{
if
(
_isNeedDisposed
)
return
-
1
;
/// live not support
await
_initPlayer
.
future
;
return
-
1
;
if
(
Platform
.
isAndroid
)
{
}
return
await
_channel
.
invokeMethod
(
"enterPictureInPictureMode"
,
{
"backIcon"
:
backIconForAndroid
,
/// 退出画中画,如果该播放器处于画中画模式
"playIcon"
:
playIconForAndroid
,
@override
"pauseIcon"
:
pauseIconForAndroid
,
Future
<
void
>
exitPictureInPictureMode
()
async
{
"forwardIcon"
:
forwardIconForAndroid
/// live not support
});
}
else
if
(
Platform
.
isIOS
)
{
return
-
1
;
}
else
{
return
-
1
;
}
}
}
/// 释放播放器资源占用
/// 释放播放器资源占用
...
...
Flutter/lib/Core/txplayer_controller.dart
浏览文件 @
22901bfd
...
@@ -23,4 +23,6 @@ abstract class TXPlayerController {
...
@@ -23,4 +23,6 @@ abstract class TXPlayerController {
Future
<
bool
>
enableHardwareDecode
(
bool
enable
);
Future
<
bool
>
enableHardwareDecode
(
bool
enable
);
Future
<
int
>
enterPictureInPictureMode
(
Future
<
int
>
enterPictureInPictureMode
(
{
String
?
backIconForAndroid
,
String
?
playIconForAndroid
,
String
?
pauseIconForAndroid
,
String
?
forwardIconForAndroid
});
{
String
?
backIconForAndroid
,
String
?
playIconForAndroid
,
String
?
pauseIconForAndroid
,
String
?
forwardIconForAndroid
});
Future
<
void
>
exitPictureInPictureMode
();
void
dispose
();
}
}
\ No newline at end of file
Flutter/lib/Core/txplayer_define.dart
浏览文件 @
22901bfd
...
@@ -304,6 +304,14 @@ class TXVodDownloadMedialnfo {
...
@@ -304,6 +304,14 @@ class TXVodDownloadMedialnfo {
}
}
}
}
///
/// 播放器类型
///
abstract
class
TXPlayerType
{
static
const
VOD_PLAY
=
0
;
static
const
LIVE_PLAY
=
1
;
}
//视频预下载事件回调Listener
//视频预下载事件回调Listener
typedef
FTXPredownlodOnCompleteListener
=
void
Function
(
int
taskId
,
String
url
);
typedef
FTXPredownlodOnCompleteListener
=
void
Function
(
int
taskId
,
String
url
);
typedef
FTXPredownlodOnErrorListener
=
void
Function
(
int
taskId
,
String
url
,
int
code
,
String
msg
);
typedef
FTXPredownlodOnErrorListener
=
void
Function
(
int
taskId
,
String
url
,
int
code
,
String
msg
);
...
...
Flutter/lib/Core/txvodplayer_controller.dart
浏览文件 @
22901bfd
...
@@ -424,6 +424,14 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
...
@@ -424,6 +424,14 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
return
await
_channel
.
invokeMethod
(
"getDuration"
);
return
await
_channel
.
invokeMethod
(
"getDuration"
);
}
}
/// 退出画中画,如果该播放器处于画中画模式
@override
Future
<
void
>
exitPictureInPictureMode
()
async
{
if
(
_isNeedDisposed
)
return
;
await
_initPlayer
.
future
;
return
await
_channel
.
invokeMethod
(
"exitPictureInPictureMode"
);
}
/// 释放controller
/// 释放controller
@override
@override
void
dispose
()
async
{
void
dispose
()
async
{
...
@@ -465,4 +473,5 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
...
@@ -465,4 +473,5 @@ class TXVodPlayerController extends ChangeNotifier implements ValueListenable<TX
double
?
videoTop
=
0
;
double
?
videoTop
=
0
;
double
?
videoRight
=
0
;
double
?
videoRight
=
0
;
double
?
videoBottom
=
0
;
double
?
videoBottom
=
0
;
}
}
Flutter/superplayer_widget/lib/demo_superplayer_lib.dart
浏览文件 @
22901bfd
...
@@ -25,8 +25,10 @@ part 'cgi/playinfo_protocol.dart';
...
@@ -25,8 +25,10 @@ part 'cgi/playinfo_protocol.dart';
part
'cgi/super_vod_data_loader.dart'
;
part
'cgi/super_vod_data_loader.dart'
;
part
'model/superplayer_define.dart'
;
part
'model/superplayer_define.dart'
;
part
'model/superplayer_model.dart'
;
part
'model/superplayer_model.dart'
;
part
'model/txpipplayer_data.dart'
;
part
'tools/video_quality_utils.dart'
;
part
'tools/video_quality_utils.dart'
;
part
'tools/utils.dart'
;
part
'tools/utils.dart'
;
part
'tools/txpip_controller.dart'
;
part
'ui/superplayer_bottom_view.dart'
;
part
'ui/superplayer_bottom_view.dart'
;
part
'ui/superplayer_quality_view.dart'
;
part
'ui/superplayer_quality_view.dart'
;
part
'ui/superplayer_title_view.dart'
;
part
'ui/superplayer_title_view.dart'
;
...
...
Flutter/superplayer_widget/lib/model/txpipplayer_data.dart
0 → 100644
浏览文件 @
22901bfd
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
/// 画中画状态存储参数
class
TXPipPlayerData
{
/// 画中画播放器实例,同时只能存在一个
final
TXPlayerController
_playerController
;
int
playerMode
=
TXPlayerType
.
VOD_PLAY
;
TXPipPlayerData
(
this
.
_playerController
)
{
playerMode
=
_playerController
is
TXVodPlayerController
?
TXPlayerType
.
VOD_PLAY
:
playerMode
=
TXPlayerType
.
LIVE_PLAY
;
}
}
Flutter/superplayer_widget/lib/superplayer_controller.dart
浏览文件 @
22901bfd
...
@@ -70,7 +70,7 @@ class SuperPlayerController {
...
@@ -70,7 +70,7 @@ class SuperPlayerController {
}
}
void
_initVodPlayer
()
async
{
void
_initVodPlayer
()
async
{
_vodPlayerController
=
new
TXVodPlayerController
();
_vodPlayerController
=
TXVodPlayerController
();
await
_vodPlayerController
.
initialize
();
await
_vodPlayerController
.
initialize
();
_setVodListener
();
_setVodListener
();
}
}
...
@@ -349,8 +349,9 @@ class SuperPlayerController {
...
@@ -349,8 +349,9 @@ class SuperPlayerController {
_playVodUrl
(
videoUrl
);
_playVodUrl
(
videoUrl
);
List
<
VideoQuality
>?
qualityList
=
protocol
.
getVideoQualityList
();
List
<
VideoQuality
>?
qualityList
=
protocol
.
getVideoQualityList
();
_isMultiBitrateStream
=
_isMultiBitrateStream
=
protocol
.
getResolutionNameList
()
!=
null
||
protocol
.
getResolutionNameList
()
!=
null
||
qualityList
!=
null
||
(
videoUrl
!=
null
&&
videoUrl
.
contains
(
"m3u8"
));
qualityList
!=
null
||
(
videoUrl
!=
null
&&
videoUrl
.
contains
(
"m3u8"
));
_updateVideoQualityList
(
qualityList
,
protocol
.
getDefaultVideoQuality
());
_updateVideoQualityList
(
qualityList
,
protocol
.
getDefaultVideoQuality
());
}
}
...
@@ -416,7 +417,8 @@ class SuperPlayerController {
...
@@ -416,7 +417,8 @@ class SuperPlayerController {
if
(
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_PRELOAD
)
{
if
(
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_PRELOAD
)
{
await
_vodPlayerController
.
setAutoPlay
(
isAutoPlay:
false
);
await
_vodPlayerController
.
setAutoPlay
(
isAutoPlay:
false
);
_playAction
=
SuperPlayerModel
.
PLAY_ACTION_AUTO_PLAY
;
_playAction
=
SuperPlayerModel
.
PLAY_ACTION_AUTO_PLAY
;
}
else
if
(
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_AUTO_PLAY
||
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_MANUAL_PLAY
)
{
}
else
if
(
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_AUTO_PLAY
||
_playAction
==
SuperPlayerModel
.
PLAY_ACTION_MANUAL_PLAY
)
{
await
_vodPlayerController
.
setAutoPlay
(
isAutoPlay:
true
);
await
_vodPlayerController
.
setAutoPlay
(
isAutoPlay:
true
);
}
}
_setVodListener
();
_setVodListener
();
...
@@ -586,7 +588,9 @@ class SuperPlayerController {
...
@@ -586,7 +588,9 @@ class SuperPlayerController {
String
title
=
""
;
String
title
=
""
;
if
(
videoModel
!=
null
&&
null
!=
videoModel
!.
title
&&
videoModel
!.
title
.
isNotEmpty
)
{
if
(
videoModel
!=
null
&&
null
!=
videoModel
!.
title
&&
videoModel
!.
title
.
isNotEmpty
)
{
title
=
videoModel
!.
title
;
title
=
videoModel
!.
title
;
}
else
if
(
_currentProtocol
!=
null
&&
null
!=
_currentProtocol
!.
getName
()
&&
_currentProtocol
!.
getName
()!.
isNotEmpty
)
{
}
else
if
(
_currentProtocol
!=
null
&&
null
!=
_currentProtocol
!.
getName
()
&&
_currentProtocol
!.
getName
()!.
isNotEmpty
)
{
title
=
_currentProtocol
!.
getName
()!;
title
=
_currentProtocol
!.
getName
()!;
}
}
return
title
;
return
title
;
...
@@ -622,7 +626,8 @@ class SuperPlayerController {
...
@@ -622,7 +626,8 @@ class SuperPlayerController {
/// 是否是HTTP-FLV协议
/// 是否是HTTP-FLV协议
bool
_isFLVPlay
(
String
?
videoURL
)
{
bool
_isFLVPlay
(
String
?
videoURL
)
{
return
(
null
!=
videoURL
&&
videoURL
.
startsWith
(
"http://"
)
||
videoURL
!.
startsWith
(
"https://"
))
&&
videoURL
.
contains
(
".flv"
);
return
(
null
!=
videoURL
&&
videoURL
.
startsWith
(
"http://"
)
||
videoURL
!.
startsWith
(
"https://"
))
&&
videoURL
.
contains
(
".flv"
);
}
}
/// 重置播放器状态
/// 重置播放器状态
...
@@ -655,10 +660,13 @@ class SuperPlayerController {
...
@@ -655,10 +660,13 @@ class SuperPlayerController {
Future
<
void
>
releasePlayer
()
async
{
Future
<
void
>
releasePlayer
()
async
{
// 先移除widget的事件监听
// 先移除widget的事件监听
_observer
?.
onDispose
();
_observer
?.
onDispose
();
resetPlayer
();
playerStreamController
.
close
();
playerStreamController
.
close
();
_vodPlayerController
.
dispose
();
// 如果处于画中画模式,播放器暂时不释放
_livePlayerController
.
dispose
();
if
(!
TXPipController
.
instance
.
isPlayerInPip
(
getCurrentController
()))
{
resetPlayer
();
_vodPlayerController
.
dispose
();
_livePlayerController
.
dispose
();
}
}
}
/// return true : 执行了退出全屏等操作,消耗了返回事件 false:未消耗事件
/// return true : 执行了退出全屏等操作,消耗了返回事件 false:未消耗事件
...
@@ -740,14 +748,21 @@ class SuperPlayerController {
...
@@ -740,14 +748,21 @@ class SuperPlayerController {
/// </h1>
/// </h1>
/// @param backIcon playIcon pauseIcon forwardIcon 为播放后退、播放、暂停、前进的图标,如果赋值的话,将会使用传递的图标,否则
/// @param backIcon playIcon pauseIcon forwardIcon 为播放后退、播放、暂停、前进的图标,如果赋值的话,将会使用传递的图标,否则
/// 使用系统默认图标,只支持flutter本地资源图片,传递的时候,与flutter使用图片资源一致,例如: images/back_icon.png
/// 使用系统默认图标,只支持flutter本地资源图片,传递的时候,与flutter使用图片资源一致,例如: images/back_icon.png
Future
<
int
>
enterPictureInPictureMode
({
String
?
backIcon
,
String
?
playIcon
,
String
?
pauseIcon
,
String
?
forwardIcon
})
async
{
Future
<
int
>
enterPictureInPictureMode
(
{
String
?
backIcon
,
String
?
playIcon
,
String
?
pauseIcon
,
String
?
forwardIcon
})
async
{
if
(
_playerUIStatus
==
SuperPlayerUIStatus
.
WINDOW_MODE
)
{
if
(
_playerUIStatus
==
SuperPlayerUIStatus
.
WINDOW_MODE
)
{
if
(
playerType
==
SuperPlayerType
.
VOD
)
{
if
(
playerType
==
SuperPlayerType
.
VOD
)
{
return
_vodPlayerController
.
enterPictureInPictureMode
(
return
TXPipController
.
instance
.
enterPip
(
_vodPlayerController
,
_context
,
backIconForAndroid:
backIcon
,
playIconForAndroid:
playIcon
,
pauseIconForAndroid:
pauseIcon
,
forwardIconForAndroid:
forwardIcon
);
backIconForAndroid:
backIcon
,
playIconForAndroid:
playIcon
,
pauseIconForAndroid:
pauseIcon
,
forwardIconForAndroid:
forwardIcon
);
}
else
{
}
else
{
return
_livePlayerController
.
enterPictureInPictureMode
(
return
TXPipController
.
instance
.
enterPip
(
_livePlayerController
,
_context
,
backIconForAndroid:
backIcon
,
playIconForAndroid:
playIcon
,
pauseIconForAndroid:
pauseIcon
,
forwardIconForAndroid:
forwardIcon
);
backIconForAndroid:
backIcon
,
playIconForAndroid:
playIcon
,
pauseIconForAndroid:
pauseIcon
,
forwardIconForAndroid:
forwardIcon
);
}
}
}
}
return
TXVodPlayEvent
.
ERROR_PIP_CAN_NOT_ENTER
;
return
TXVodPlayEvent
.
ERROR_PIP_CAN_NOT_ENTER
;
...
@@ -794,6 +809,14 @@ class SuperPlayerController {
...
@@ -794,6 +809,14 @@ class SuperPlayerController {
}
}
}
}
/// 设置播放开始时间
Future
<
void
>
setStartTime
(
double
startTime
)
async
{
if
(
playerType
==
SuperPlayerType
.
VOD
)
{
startPos
=
startTime
;
return
await
_vodPlayerController
.
setStartTime
(
startTime
);
}
}
Future
<
void
>
setPlayRate
(
double
rate
)
async
{
Future
<
void
>
setPlayRate
(
double
rate
)
async
{
currentPlayRate
=
rate
;
currentPlayRate
=
rate
;
_vodPlayerController
.
setRate
(
rate
);
_vodPlayerController
.
setRate
(
rate
);
...
...
Flutter/superplayer_widget/lib/tools/txpip_controller.dart
0 → 100644
浏览文件 @
22901bfd
// Copyright (c) 2022 Tencent. All rights reserved.
part of
demo_super_player_lib
;
typedef
OnJumpToPipPlayer
=
void
Function
(
Map
params
);
typedef
OnPopCurrent
=
void
Function
();
///
/// 画中画控制器,单例,只能存在一个画中画
///
class
TXPipController
{
static
const
ARGUMENT_PIP_START_TIME
=
"argumentStartTime"
;
static
TXPipController
?
_instance
;
static
TXPipController
get
instance
=>
_sharedInstance
();
/// 画中画播放器实例,同时只能存在一个
TXPipPlayerData
?
_playerData
;
final
Map
<
String
,
dynamic
>
_extParams
=
{};
TXPipPlayerRestorePage
?
_onPipEnterListener
;
OnJumpToPipPlayer
?
_onJumpToPipPlayer
;
StreamSubscription
?
_pipEventSubscription
;
/// TXPipController
static
TXPipController
_sharedInstance
()
{
_instance
??=
TXPipController
.
_internal
();
return
_instance
!;
}
TXPipController
.
_internal
();
Future
<
int
>
enterPip
(
TXPlayerController
playerController
,
BuildContext
context
,
{
String
?
backIconForAndroid
,
String
?
playIconForAndroid
,
String
?
pauseIconForAndroid
,
String
?
forwardIconForAndroid
})
async
{
if
(
_playerData
!=
null
)
{
await
exitAndReleaseCurrentPip
();
}
_playerData
=
TXPipPlayerData
(
playerController
);
_pipEventSubscription
=
SuperPlayerPlugin
.
instance
.
onExtraEventBroadcast
.
listen
((
event
)
async
{
int
eventCode
=
event
[
"event"
];
if
((
Platform
.
isIOS
&&
eventCode
==
TXVodPlayEvent
.
EVENT_PIP_MODE_ALREADY_ENTER
)
||
(
Platform
.
isAndroid
&&
eventCode
==
TXVodPlayEvent
.
EVENT_PIP_MODE_REQUEST_START
))
{
_onPipEnterListener
?.
onNeedSavePipPageState
(
_extParams
);
Navigator
.
of
(
context
).
pop
();
}
else
if
((
Platform
.
isIOS
&&
eventCode
==
TXVodPlayEvent
.
EVENT_IOS_PIP_MODE_WILL_EXIT
)
||
(
Platform
.
isAndroid
&&
eventCode
==
TXVodPlayEvent
.
EVENT_PIP_MODE_ALREADY_EXIT
))
{
await
exitAndReleaseCurrentPip
();
}
else
if
(
eventCode
==
TXVodPlayEvent
.
EVENT_IOS_PIP_MODE_RESTORE_UI
)
{
_extParams
[
ARGUMENT_PIP_START_TIME
]
=
event
[
"playTime"
];
await
exitAndReleaseCurrentPip
();
_onJumpToPipPlayer
?.
call
(
_extParams
);
}
else
if
(
eventCode
<
0
)
{
// pip enter failed
_pipEventSubscription
?.
cancel
();
_playerData
=
null
;
}
});
int
enterResult
=
await
_playerData
!.
_playerController
.
enterPictureInPictureMode
(
backIconForAndroid:
backIconForAndroid
,
playIconForAndroid:
playIconForAndroid
,
pauseIconForAndroid:
pauseIconForAndroid
,
forwardIconForAndroid:
forwardIconForAndroid
);
if
(
enterResult
!=
TXVodPlayEvent
.
NO_ERROR
)
{
_playerData
=
null
;
_pipEventSubscription
?.
cancel
();
}
return
enterResult
;
}
Future
<
void
>
exitAndReleaseCurrentPip
()
async
{
if
(
null
!=
_playerData
&&
_playerData
?.
_playerController
!=
null
)
{
if
(
Platform
.
isAndroid
)
{
await
_playerData
?.
_playerController
.
exitPictureInPictureMode
();
}
await
_playerData
?.
_playerController
.
stop
();
_playerData
?.
_playerController
.
dispose
();
}
_pipEventSubscription
?.
cancel
();
_playerData
=
null
;
}
/// 传入的controller是否处于画中画模式
bool
isPlayerInPip
(
TXPlayerController
playerController
)
{
if
(
null
!=
_playerData
)
{
return
_playerData
!.
_playerController
==
playerController
;
}
return
false
;
}
void
setPipPlayerPage
(
Type
a
,
TXPipPlayerRestorePage
listener
)
{
_onPipEnterListener
=
listener
;
}
void
setNavigatorHandle
(
OnJumpToPipPlayer
onJumpToPipPlayer
)
{
_onJumpToPipPlayer
=
onJumpToPipPlayer
;
}
}
abstract
class
TXPipPlayerRestorePage
{
/// 当需要保存画中画界面相关元素的时候,会回调该方法
void
onNeedSavePipPageState
(
Map
<
String
,
dynamic
>
params
);
}
Flutter/superplayer_widget/lib/ui/superplayer_widget.dart
浏览文件 @
22901bfd
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论