赞
踩
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical">
<Text
ohos:height="match_content"
ohos:width="match_content"
ohos:text="AAA"
ohos:text_size="30fp"/>
<DirectionalLayout
ohos:id="$+id:direction_layout2"
ohos:height="250vp"
ohos:width="match_parent"
ohos:alignment="center"
ohos:background_element="#000000">
<SurfaceProvider
ohos:id="$+id:surface_provider"
ohos:height="match_parent"
ohos:width="match_parent"/>
</DirectionalLayout>
</DirectionalLayout>
效果图如下
/**
* Thread pool manager.Copyright (c) 2021 Huawei Device Co., Ltd....
*/
public class ThreadPoolManager {
private static final int CPU_COUNT = 20;
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE = 1;
private static ThreadPoolManager instance;
private ThreadPoolExecutor executor;
private ThreadPoolManager() {
if (executor == null) {
executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(20), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
}
/**
* Create ThreadPoolManager object.
*
* @return ThreadPoolManager.
*/
public static synchronized ThreadPoolManager getInstance() {
if (instance == null) {
synchronized (ThreadPoolManager.class) {
if (instance == null) {
instance = new ThreadPoolManager();
}
}
}
return instance;
}
/**
* Start a thread that does not return any information.
*
* @param runnable Runnable.
*/
public void execute(Runnable runnable) {
executor.execute(runnable);
}
/**
* Remove runnable.
*
* @param runnable Runnable.
*/
public void cancel(Runnable runnable) {
if (runnable != null) {
executor.getQueue().remove(runnable);
}
}
}
/**
* VideoPlayerPlugin Copyright (c) 2021 Huawei Device Co., Ltd.
*/
public class VideoPlayerPlugin {
private static final String TAG = VideoPlayerPlugin.class.getSimpleName();
private static final int REWIND_TIME = 2000;
private final Context context;
private Player videoPlayer;
private Runnable videoRunnable;
/**
* VideoPlayerPlugin
*
* @param sliceContext Context
*/
public VideoPlayerPlugin(Context sliceContext) {
context = sliceContext;
}
/**
* start
*/
public synchronized void startPlay() {
if (videoPlayer == null) {
return;
}
videoPlayer.play();
LogUtil.info(TAG, "start play");
}
/**
* Set source,prepare,start
*
* @param avElement AVElement
* @param surface Surface
*/
public synchronized void startPlay(AVElement avElement, Surface surface) {
if (videoPlayer != null) {
videoPlayer.stop();
videoPlayer.release();
videoPlayer = null;
}
if (videoRunnable != null) {
ThreadPoolManager.getInstance().cancel(videoRunnable);
}
videoPlayer = new Player(context);
videoPlayer.setPlayerCallback(new VideoCallBack());
videoRunnable = () -> play(avElement, surface);
ThreadPoolManager.getInstance().execute(videoRunnable);
}
/**
* pause
*/
public synchronized void pausePlay() {
if (videoPlayer == null) {
return;
}
videoPlayer.pause();
LogUtil.info(TAG, "pause play");
}
public synchronized void enableSingleLooping(boolean enable) {
if (videoPlayer == null) {
return;
}
videoPlayer.enableSingleLooping(enable);
LogUtil.info(TAG, "enableSingleLooping");
}
private void play(AVElement avElement, Surface surface) {
Source source = new Source(avElement.getAVDescription().getMediaUri().toString());
videoPlayer.setSource(source);
videoPlayer.setVideoSurface(surface);
LogUtil.info(TAG, source.getUri());
videoPlayer.prepare();
videoPlayer.play();
}
/**
* seek
*/
public void seek() {
if (videoPlayer == null) {
return;
}
videoPlayer.rewindTo(videoPlayer.getCurrentTime() + REWIND_TIME);
LogUtil.info(TAG, "seek" + videoPlayer.getCurrentTime());
}
/**
* release player
*/
public void release() {
if (videoPlayer != null) {
videoPlayer.stop();
videoPlayer.release();
videoPlayer = null;
}
}
private static class VideoCallBack implements Player.IPlayerCallback {
@Override
public void onPrepared() {
LogUtil.info(TAG, "onPrepared");
}
@Override
public void onMessage(int type, int extra) {
LogUtil.info(TAG, "onMessage" + type);
}
@Override
public void onError(int errorType, int errorCode) {
LogUtil.error(TAG, "onError" + errorType);
}
@Override
public void onResolutionChanged(int width, int height) {
LogUtil.info(TAG, "onResolutionChanged" + width);
}
@Override
public void onPlayBackComplete() {
LogUtil.info(TAG, "onPlayBackComplete");
}
@Override
public void onRewindToComplete() {
LogUtil.info(TAG, "onRewindToComplete");
}
@Override
public void onBufferingChange(int percent) {
LogUtil.info(TAG, "onBufferingChange" + percent);
}
@Override
public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) {
LogUtil.info(TAG, "onNewTimedMetaData" + mediaTimedMetaData.toString());
}
@Override
public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {
LogUtil.info(TAG, "onNewTimedMetaData" + mediaTimeInfo.toString());
}
}
}
public class MainAbility2Slice extends AbilitySlice {
private static final String TAG = MainAbility2Slice.class.getSimpleName();
private SurfaceProvider surfaceProvider;
private Surface surface;
private static final String WEB_VIDEO_PATH = "https://ss0.bdstatic.com/-0U0bnSm1A5BphGlnYG/"
+ "cae-legoup-video-target/93be3d88-9fc2-4fbd-bd14-833bca731ca7.mp4";
private VideoPlayerPlugin videoPlayerPlugin;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main2);
addSurfaceProvider();
initPlayer();
AVDescription bean =
new AVDescription.Builder()
.setTitle("web_video_01")
.setIMediaUri(Uri.parse(WEB_VIDEO_PATH))
.setMediaId(WEB_VIDEO_PATH)
.build();
AVElement avElement = new AVElement(bean, AVElement.AVELEMENT_FLAG_PLAYABLE);
ThreadPoolManager.getInstance().execute(() -> {
while (surface == null) {
}
videoPlayerPlugin.startPlay(avElement, surface);
videoPlayerPlugin.enableSingleLooping(true);
});
}
private void initPlayer() {
videoPlayerPlugin = new VideoPlayerPlugin(getApplicationContext());
}
private void addSurfaceProvider() {
surfaceProvider = (SurfaceProvider) findComponentById(ResourceTable.Id_surface_provider);
if (surfaceProvider.getSurfaceOps().isPresent()) {
surfaceProvider.getSurfaceOps().get().addCallback(new MainAbility2Slice.SurfaceCallBack());
// 当surfaceProvider设置为“pinToZTop(true)”时,视频窗口显示在最前面,其他控件无法显示。
// 当surfaceProvider设置为“pinToZTop(false)”时,视频窗口不会显示在最前面,
// 支持其他控件(如进度条、播放时间等)与视频播放页面同时显示,但需要保证其他控件与surfaceProvider在同一layout下,并且不能设置背景。
surfaceProvider.pinToZTop(true);
}
}
/**
* SurfaceCallBack
* 用于感知Surface的创建、销毁或者改变
*/
class SurfaceCallBack implements SurfaceOps.Callback {
@Override
public void surfaceCreated(SurfaceOps callbackSurfaceOps) {
if (surfaceProvider.getSurfaceOps().isPresent()) {
surface = surfaceProvider.getSurfaceOps().get().getSurface();
}
}
@Override
public void surfaceChanged(SurfaceOps callbackSurfaceOps, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceOps callbackSurfaceOps) {
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。