如何在移动操作系统中创建并使用短视频播放器,阿里云视频直播已经有一套完善的关键实现机制确保视频的播放。
效果展示
短视频列表播放器的效果展示,请参见效果展示。
Android关键实现
播放器其他的接口可根据实际需求调用。请参考功能文档或者接口文档。
执行以下操作,完成Android关键实现。
- 创建列表播放器,并设置相关参数。
private AliListPlayer mVideoListPlayer; …… //创建播放器(必须) mVideoListPlayer = AliPlayerFactory.createAliListPlayer(mContext); //开启硬解 mVideoListPlayer.enableHardwareDecoder(true); //设置播放器参数 PlayerConfig config = mVideoListPlayer.getConfig(); //停止之后清空画面。防止画面残留(建议设置) config.mClearFrameWhenStop = true; mVideoListPlayer.setConfig(config); //开启循环播放。短视频一般都是循环播放的 mVideoListPlayer.setLoop(true); //开启自动播放。 mVideoListPlayer.setAutoPlay(true); //设置预加载个数。此时会加载3个视频。当前播放的,和上下1个。 mVideoListPlayer.setPreloadCount(1);
- 添加多个播放数据源。
列表播放器支持URL、点播Vid的数据源(STS方式)。
//使用点播服务的视频源 mVideoListPlayer.addVid("点播视频vid", "视频唯一标识"); //或者直接使用URL mVideoListPlayer.addUrl("视频URL", "视频唯一标识");
在列表播放器内部,视频是通过视频唯一标识区分的。视频唯一标识可以是任意自定义的字符串,比如:UUID。如果添加的视频源的唯一标识一样的话,会导致播放错乱。所以,确保每次添加数据源的视频唯一标识都不一样。
- 开始播放某个视频。
播放器提供了以下接口,实现基本的定位播放功能:moveTo,moveToPrev,moveToNext。
//直接跳转到某个视频播放 mVideoListPlayer.moveTo("视频唯一标识",STS信息) //点播Vid源(STS方式) mVideoListPlayer.moveTo("视频唯一标识") //URL源 //播放上一个视频 mVideoListPlayer.moveToPrev("视频唯一标识",STS信息) //点播Vid源(STS方式) mVideoListPlayer.moveToPrev("视频唯一标识") //URL源 //播放下一个视频 mVideoListPlayer.moveToNext("视频唯一标识",STS信息) //点播Vid源(STS方式) mVideoListPlayer.moveToNext("视频唯一标识") //URL源
- TextureView与播放器的配合使用。
多数列表播放使用了TextureView。正确的使用,可以避免退后台返回黑屏的问题,优化播放体验。
- TextureView的基本设置。
TextureView mTextureView = null; SurfaceTexture mSurfaceTexture = null; Surface mSurface = null; …… mTextureView = findViewById(R.id.textureView); mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { //缓存SurfaceTexture,在退后台再进时使用 mSurfaceTexture = surfaceTexture; mSurface = new Surface(surface); //设置播放的surface mVideoListPlayer.setSurface(mSurface); } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { //画面大小变化的时候重绘界面,立即刷新界面 mVideoListPlayer.redraw(); } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { //这里一定要return false。这样SurfaceTexture不会被系统销毁 return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } });
- 退后台重进界面。
在onResume中处理退后台再进的情况 public void onResume() { …… if (mVideoListPlayer != null && mSurface != null) { mVideoListPlayer.setSurface(mSurface); mVideoListPlayer.redraw(); } …… }
- TextureView的基本设置。
- 封面的隐藏时机。
列表播放时一般都会有个封面,视频播起来之后,把封面隐藏,显示视频。
mVideoListPlayer.setOnRenderingStartListener(new IPlayer.OnRenderingStartListener() { @Override public void onRenderingStart() { //视频第一帧开始渲染。此时可以隐藏封面 } });
- 销毁播放器。
退出界面,使用完播放器,需要释放播放器。否则会有内存泄漏。
//释放surface mVideoListPlayer.setSurface(null); //如果按照第4步使用了TextureView,那么还需要释放缓存的surface if (mSurface != null) { mSurface.release(); } if (mSurfaceTexture != null) { mSurfaceTexture.release(); } //释放播放器 mVideoListPlayer.release();
iOS关键实现
播放器其他的接口可根据实际需求调用。请参考功能文档或者接口文档。
执行以下操作,完成iOS关键实现。
- 创建列表播放器,并设置相关参数。
//创建播放器(必须) self.listPlayer = [[AliListPlayer alloc]init]; //开启硬解 self.listPlayer.enableHardwareDecoder = YES; //循环播放 self.listPlayer.loop = YES; //自动播放 self.listPlayer.autoPlay = YES; //渲染模式 self.listPlayer.scalingMode = AVP_SCALINGMODE_SCALEASPECTFIT; //代理设置 self.listPlayer.delegate = self; //预加载的清晰度 self.listPlayer.stsPreloadDefinition = @"FD"; //显示view self.listPlayer.playerView = self.simplePlayScrollView.playView; //设置预加载个数。此时会加载3个视频。当前播放的,和上下1个。 mVideoListPlayer.setPreloadCount(1);
- 添加多个播放数据源。
列表播放器支持URL、点播Vid的数据源(STS方式)。
//使用点播服务的视频源 [self.listPlayer addVidSource:点播视频vid uid:"视频唯一标识"]; //或者直接使用URL [self.listPlayer addUrlSource:"视频URL" uid: "视频唯一标识"];
在列表播放器内部,视频是通过视频唯一标识区分的。如果添加的视频源的唯一标识一样的话,会导致播放错乱。所以,确保每次添加数据源的视频唯一标识都不一样。
- 开始播放某个视频。
播放器提供了以下接口,实现基本的定位播放功能:moveTo,moveToPrev,moveToNecxt。
//直接跳转到某个视频播放 [self.listPlayer moveTo:"视频唯一标识"]; //URL源 [self.listPlayer moveTo:"视频唯一标识" accId:accId accKey:accKey token:token region:region]; //点播Vid源(STS方式) //播放上一个视频 [self.listPlayer moveToPrev:"视频唯一标识"]; //URL源 [self.listPlayer moveToPrev:"视频唯一标识" accId:accId accKey:accKey token:token region:region]; //点播Vid源(STS方式) //播放下一个视频 [self.listPlayer moveToNext:"视频唯一标识"]; //URL源 [self.listPlayer moveToNext:"视频唯一标识" accId:accId accKey:accKey token:token region:region]; //点播Vid源(STS方式)
- 滑动控制操作。
下面列举一些滑动播放控制操作。
- 单击暂停和播放。
- (void)tap { if ([self.delegate respondsToSelector:@selector(AVPSimplePlayScrollViewTapGestureAction:)]) { [self.delegate AVPSimplePlayScrollViewTapGestureAction:self]; } } - (void)AVPSimplePlayScrollViewTapGestureAction:(AVPSimplePlayScrollView *)simplePlayScrollView { if (self.playerStatus == AVPStatusStarted) { //如果是播放,则暂停 [self.listPlayer pause]; }else if (self.playerStatus == AVPStatusPaused) { //如果是暂停,则播放 [self.listPlayer start]; } }
- 滑动控制。
如果列表滑动速度较快,也就是滑动的位置超过一个,则直接调用moveTo接口列表滑动后的回调中去判定。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { CGFloat indexFloat = scrollView.contentOffset.y/self.frame.size.height; NSInteger index = (NSInteger)indexFloat; ....... //往下滑动一格 if (index - self.currentIndex == 1) { if ([self.delegate respondsToSelector:@selector(AVPSimplePlayScrollView:motoNextAtIndex:)]) { [self.delegate AVPSimplePlayScrollView:self motoNextAtIndex:index]; } } //往上滑动一格 else if (self.currentIndex - index == 1){ if ([self.delegate respondsToSelector:@selector(AVPSimplePlayScrollView:motoPreAtIndex:)]) { [self.delegate AVPSimplePlayScrollView:self motoPreAtIndex:index]; } } //滑动多格 else { if ([self.delegate respondsToSelector:@selector(AVPSimplePlayScrollView:scrollViewDidEndDeceleratingAtIndex:)]) { [self.delegate AVPSimplePlayScrollView:self scrollViewDidEndDeceleratingAtIndex:index]; } } } /** 滚动事件,移动位置超过一个 @param simplePlayScrollView simplePlayScrollView @param index 移动到第几个 */ - (void)AVPSimplePlayScrollView:(AVPSimplePlayScrollView *)simplePlayScrollView scrollViewDidEndDeceleratingAtIndex:(NSInteger)index { //找到第几个 AVPDemoResponseVideoListModel *model = [self findModelFromIndex:index]; //MoveTo到当前 [self moveToCurrentModel];
- 单击暂停和播放。
- 封面的隐藏时机。
列表播放时一般都会有个封面,视频播起来之后,把封面隐藏,显示视频。
-(void)onPlayerEvent:(AliPlayer*)player eventType:(AVPEventType)eventType { switch (eventType) { case AVPEventPrepareDone: { } break; case AVPEventFirstRenderedStart: { //隐藏封面图 [self.simplePlayScrollView showPlayView]; } break; default: break; } }
- 退出界面,使用完播放器,需要释放播放器。否则会有内存泄漏。
退出界面,使用完播放器,需要释放播放器。否则会有内存泄漏。
[self.listPlayer stop]; [self.listPlayer destroy]; self.listPlayer = nil;