【软通动力】SurfaceProvider实现视频播放Demo-热乎乎的拜年视频 精华

软通小精灵
发布于 2021-2-8 16:12
浏览
7收藏

 
        辛丑年即将到来,基于HOS,利用SurfaceProvider控件实现了一个视频播放的Demo,有开始、暂停和循环播放功能,邀请大家一起来看看。提前祝51CTO的广大开发爱好者新春快乐!牛气冲天!
        奉上视频一睹为快。

具体实现步骤如下:
一.创建布局:

<?xml version="1.0" encoding="utf-8"?>
 <StackLayout
       xmlns:ohos="http://schemas.huawei.com/res/ohos"
       ohos:width="match_parent"
       ohos:height="match_parent">
      <ohos.agp.components.surfaceprovider.SurfaceProvider
        ohos:id="$+id:surfaceProvider"
        ohos:width="match_parent"
        ohos:height="match_parent"/>
       <Image
           ohos:id="$+id:img"
           ohos:height="match_content"
           ohos:width="match_content"
           ohos:image_src="$media:player"
           ohos:layout_alignment="center"
           ohos:visibility="hide"/>
   </StackLayout>

二、在MainAbilitySlice实现播放功能的代码

onStart()中添加:
//设置沉浸式状态栏
getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
initPlayer();
需要重写两个回调:VideoSurfaceCallback 、VideoPlayerCallback
private void initPlayer() {
    sfProvider=(SurfaceProvider) findComponentById(ResourceTable.Id_surfaceProvider);
    image=(Image) findComponentById(ResourceTable.Id_img);
    sfProvider.getSurfaceOps().get().addCallback(new VideoSurfaceCallback());
    //sfProvider.pinToZTop(boolean)--如果设置为true, 视频控件会在最上次展示,但是设置为false时,虽然不在最上层展示,却出现黑屏,
    // 需加上一行代码:WindowManager.getInstance().getTopWindow().get().setTransparent(true);
    sfProvider.pinToZTop(false);
    WindowManager.getInstance().getTopWindow().get().setTransparent(true);
    player=new Player(getContext());
//sfProvider添加监听事件
    sfProvider.setClickedListener(new Component.ClickedListener() {
        @Override
        public void onClick(Component component) {
            if(player.isNowPlaying()){
                //如果正在播放,就暂停
                player.pause();
                //播放按钮可见
                image.setVisibility(Component.VISIBLE);
            }else {
                //如果暂停,点击继续播放
                player.play();
                //播放按钮隐藏
                image.setVisibility(Component.HIDE);
            }
        }
    });
}
private void playLocalFile(Surface surface) {
    try {
        RawFileDescriptor filDescriptor = getResourceManager().getRawFileEntry("resources/rawfile/123.mp4").openRawFileDescriptor();
        Source source = new Source(filDescriptor.getFileDescriptor(),filDescriptor.getStartPosition(),filDescriptor.getFileSize());
        player.setSource(source);
        player.setVideoSurface(surface);
        player.setPlayerCallback(new VideoPlayerCallback());
        player.prepare();
        sfProvider.setTop(0);
        player.play();
    } catch (Exception e) {
        HiLog.info(logLabel,"playUrl Exception:" + e.getMessage());
    }
}
private class VideoSurfaceCallback implements SurfaceOps.Callback {
    @Override
    public void surfaceCreated(SurfaceOps surfaceOps) {
        HiLog.info(logLabel,"surfaceCreated() called.");
        if (sfProvider.getSurfaceOps().isPresent()) {
            Surface surface = sfProvider.getSurfaceOps().get().getSurface();
            playLocalFile(surface);
        }
    }
    @Override
    public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {
        HiLog.info(logLabel,"surfaceChanged() called.");
    }
    @Override
    public void surfaceDestroyed(SurfaceOps surfaceOps) {
        HiLog.info(logLabel,"surfaceDestroyed() called.");
    }
}
private class VideoPlayerCallback implements Player.IPlayerCallback {
    @Override
    public void onPrepared() {
        HiLog.info(logLabel,"onPrepared");
    }
    @Override
    public void onMessage(int i, int i1) {
        HiLog.info(logLabel,"onMessage");
    }
    @Override
    public void onError(int i, int i1) {
        HiLog.info(logLabel,"onError: i=" + i + ", i1=" + i1);
    }
    @Override
    public void onResolutionChanged(int i, int i1) {
        HiLog.info(logLabel,"onResolutionChanged");
    }
    @Override
    public void onPlayBackComplete() {
        //播放完成回调,重新播放
        if (player != null) {
            player.prepare();
            player.play();
        }
    }
    @Override
    public void onRewindToComplete() {
        HiLog.info(logLabel,"onRewindToComplete");
    }
    @Override
    public void onBufferingChange(int i) {
        HiLog.info(logLabel,"onBufferingChange");
    }
    @Override
    public void onNewTimedMetaData(Player.MediaTimedMetaData mediaTimedMetaData) {
        HiLog.info(logLabel,"onNewTimedMetaData");
    }
    @Override
    public void onMediaTimeIncontinuity(Player.MediaTimeInfo mediaTimeInfo) {
        HiLog.info(logLabel,"onMediaTimeIncontinuity");
    }
}

 三 在MainAbilitySlice的其他生命周对player进行资源管理:

@Override
public void onActive() {
    super.onActive();
    player.play();
}
@Override
protected void onBackground() {
    super.onBackground();
    player.pause();
}
@Override
protected void onStop() {
    super.onStop();
    player.stop();
    player.release();
}

四、实现效果:详细请查看视频。https://harmonyos.51cto.com/show/3119【软通动力】SurfaceProvider实现视频播放Demo-热乎乎的拜年视频-鸿蒙开发者社区

欢迎交流:HWIS-HOS@isoftstone.com

已于2021-2-9 09:28:59修改
13
收藏 7
回复
举报
13条回复
按时间正序
/
按时间倒序
鸿蒙张荣超
鸿蒙张荣超

👍👍👍

回复
2021-2-9 13:43:32
Whyalone
Whyalone

厉害了,我的哥

回复
2021-2-9 15:52:57
Whyalone
Whyalone

知识点:

//设置沉浸式状态栏
getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);

回复
2021-2-9 17:43:22
软通田可辉
软通田可辉 回复了 鸿蒙张荣超
👍👍👍

张老师新年快乐

回复
2021-2-10 09:29:19
软通田可辉
软通田可辉 回复了 Whyalone
厉害了,我的哥

有了51CTO,我们会更厉害

回复
2021-2-10 09:29:57
软通田可辉
软通田可辉 回复了 Whyalone
知识点: //设置沉浸式状态栏getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);

学习课代表以后就是你了

回复
2021-2-10 09:30:21
小发哥哥
小发哥哥

新年快乐

回复
2021-2-10 14:31:23
guangyi100
guangyi100

厉害厉害

回复
2021-2-18 17:08:35
BLUESKYHOST
BLUESKYHOST

为什么我的是黑屏呢

回复
2021-3-22 16:06:33
BLUESKYHOST
BLUESKYHOST

有可以运行的demo吗  我的是黑屏

回复
2021-3-22 16:49:42
雪建到底
雪建到底

为什么最后会黑屏?求告知

回复
2021-10-11 14:33:14
雪建到底
雪建到底

WindowManager.getInstance().getTopWindow().get().setTransparent(true);

这一行代码有什么作用?求告知。

回复
2021-10-13 17:24:59
Tongson?
Tongson?

嵌套在页面上的半屏的SfProvider.pinToZTop(false); WindowManager.getInstance().getTopWindow().get().setTransparent(true);

非SfProvider部分黑了,有什么比较优雅的处理办法吗?

回复
2022-3-4 09:14:06
回复
    相关推荐