瀏覽代碼

优化视频播放器内核

yangchong 3 年之前
父節點
當前提交
6824513ac3

+ 1 - 1
ReadMeWiki/00.方案实践/00.视频播放器整体结构.md

@@ -1,4 +1,4 @@
-# 02.视频播放器整体结构
+# 视频播放器整体结构
 #### 目录介绍
 - 01.视频常见的布局视图
 - 02.后期可能涉及的视图

+ 2 - 2
VideoKernel/src/main/java/com/yc/kernel/factory/PlayerFactory.java

@@ -15,7 +15,7 @@ import com.yc.kernel.inter.AbstractVideoPlayer;
  *             2.继承此接口并实现{@link #createPlayer(Context)},返回步骤1中的播放器。
  * </pre>
  */
-public abstract class PlayerFactory<T extends AbstractVideoPlayer> {
+public interface PlayerFactory<T extends AbstractVideoPlayer> {
 
     /**
      * 使用工厂模式
@@ -31,6 +31,6 @@ public abstract class PlayerFactory<T extends AbstractVideoPlayer> {
      * @param context                       上下文
      * @return                              具体的player
      */
-    public abstract T createPlayer(Context context);
+    T createPlayer(Context context);
 
 }

+ 16 - 3
VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoMediaPlayer.java

@@ -62,6 +62,10 @@ public class ExoMediaPlayer extends AbstractVideoPlayer implements VideoListener
     private RenderersFactory mRenderersFactory;
     private TrackSelector mTrackSelector;
 
+    /**
+     * 创建对象操作
+     * @param context                           上下文
+     */
     public ExoMediaPlayer(Context context) {
         if (context instanceof Application){
             mAppContext = context;
@@ -71,6 +75,9 @@ public class ExoMediaPlayer extends AbstractVideoPlayer implements VideoListener
         mMediaSourceHelper = ExoMediaSourceHelper.getInstance(context);
     }
 
+    /**
+     * 初始化谷歌播放器
+     */
     @Override
     public void initPlayer() {
         //创建exo播放器
@@ -88,9 +95,6 @@ public class ExoMediaPlayer extends AbstractVideoPlayer implements VideoListener
         setOptions();
 
         //播放器日志
-        if (VideoLogUtils.isIsLog() && mTrackSelector instanceof MappingTrackSelector) {
-            mInternalPlayer.addAnalyticsListener(new EventLogger((MappingTrackSelector) mTrackSelector, "ExoPlayer"));
-        }
         initListener();
     }
 
@@ -98,7 +102,16 @@ public class ExoMediaPlayer extends AbstractVideoPlayer implements VideoListener
      * exo视频播放器监听listener
      */
     private void initListener() {
+        if (VideoLogUtils.isIsLog() && mTrackSelector instanceof MappingTrackSelector) {
+            EventLogger exoPlayer = new EventLogger((MappingTrackSelector) mTrackSelector, "ExoPlayer");
+            mInternalPlayer.addAnalyticsListener(exoPlayer);
+        }
+        //设置视频播放器监听
         mInternalPlayer.addListener(this);
+        //设置视频video监听
+        //onVideoSizeChanged        视频size发生了变化
+        //onSurfaceSizeChanged      视频surface变化
+        //onRenderedFirstFrame      视频第一帧
         mInternalPlayer.addVideoListener(this);
     }
 

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoMediaSourceHelper.java

@@ -42,7 +42,7 @@ public final class ExoMediaSourceHelper {
 
     private static ExoMediaSourceHelper sInstance;
     private final String mUserAgent;
-    private Context mAppContext;
+    private final Context mAppContext;
     private HttpDataSource.Factory mHttpDataSourceFactory;
     private Cache mCache;
 

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/exo/ExoPlayerFactory.java

@@ -13,7 +13,7 @@ import com.yc.kernel.factory.PlayerFactory;
  *     revise: 抽象工厂具体实现类
  * </pre>
  */
-public class ExoPlayerFactory extends PlayerFactory<ExoMediaPlayer> {
+public class ExoPlayerFactory implements PlayerFactory<ExoMediaPlayer> {
 
     public static ExoPlayerFactory create() {
         return new ExoPlayerFactory();

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/ijk/IjkPlayerFactory.java

@@ -27,7 +27,7 @@ import com.yc.kernel.factory.PlayerFactory;
  *     revise: 抽象工厂具体实现类
  * </pre>
  */
-public class IjkPlayerFactory extends PlayerFactory<IjkVideoPlayer> {
+public class IjkPlayerFactory implements PlayerFactory<IjkVideoPlayer> {
 
     public static IjkPlayerFactory create() {
         return new IjkPlayerFactory();

+ 9 - 2
VideoKernel/src/main/java/com/yc/kernel/impl/ijk/IjkVideoPlayer.java

@@ -162,9 +162,15 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
         try {
             //解析path
             Uri uri = Uri.parse(path);
-            if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme())) {
+            String scheme = uri.getScheme();
+            if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
+                //处理本地资源
                 RawDataSourceProvider rawDataSourceProvider = RawDataSourceProvider.create(mAppContext, uri);
-                mMediaPlayer.setDataSource(rawDataSourceProvider);
+                if (rawDataSourceProvider != null){
+                    mMediaPlayer.setDataSource(rawDataSourceProvider);
+                } else {
+                    mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,"path no find");
+                }
             } else {
                 //处理UA问题
                 if (headers != null) {
@@ -301,6 +307,7 @@ public class IjkVideoPlayer extends AbstractVideoPlayer {
             @Override
             public void run() {
                 try {
+                    //异步释放,防止卡顿
                     mMediaPlayer.release();
                 } catch (Exception e) {
                     e.printStackTrace();

+ 1 - 0
VideoKernel/src/main/java/com/yc/kernel/impl/media/AndroidMediaPlayer.java

@@ -202,6 +202,7 @@ public class AndroidMediaPlayer extends AbstractVideoPlayer {
             @Override
             public void run() {
                 try {
+                    //异步释放,防止卡顿
                     mMediaPlayer.release();
                 } catch (Exception e) {
                     e.printStackTrace();

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/media/MediaPlayerFactory.java

@@ -29,7 +29,7 @@ import com.yc.kernel.factory.PlayerFactory;
  *     revise: 抽象工厂具体实现类
  * </pre>
  */
-public class MediaPlayerFactory extends PlayerFactory<AndroidMediaPlayer> {
+public class MediaPlayerFactory implements PlayerFactory<AndroidMediaPlayer> {
 
     public static MediaPlayerFactory create() {
         return new MediaPlayerFactory();

+ 1 - 1
VideoKernel/src/main/java/com/yc/kernel/impl/tx/TxPlayerFactory.java

@@ -30,7 +30,7 @@ import com.yc.kernel.impl.media.AndroidMediaPlayer;
  *     revise:
  * </pre>
  */
-public class TxPlayerFactory extends PlayerFactory<TxMediaPlayer> {
+public class TxPlayerFactory implements PlayerFactory<TxMediaPlayer> {
 
     public static TxPlayerFactory create() {
         return new TxPlayerFactory();

+ 5 - 140
VideoKernel/src/main/java/com/yc/kernel/inter/AbstractVideoPlayer.java

@@ -15,160 +15,25 @@ limitations under the License.
 */
 package com.yc.kernel.inter;
 
-import android.content.res.AssetFileDescriptor;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-
-import java.util.Map;
-
 
 /**
  * <pre>
  *     @author yangchong
  *     blog  : https://github.com/yangchong211
  *     time  : 2018/11/9
- *     desc  : 抽象的播放器
- *     revise:
+ *     desc  : 抽象的播放器【所有的不同内核播放器统一继承该接口】
+ *     revise: 第一部分:通用音视频初始化接口,比如初始化音视频播放器,设置播放资源,开始播放等
+ *             第二部分:通用音视频状态接口,比如开始,暂停,结束,获取时长,设置音量等
+ *             第三部分:播放器event监听接口,比如异常,完成,准备,size变化等
  * </pre>
  */
-public abstract class AbstractVideoPlayer {
+public abstract class AbstractVideoPlayer implements InterInitPlayer, InterBasePlayer{
 
     /**
      * 播放器事件回调
      */
     protected VideoPlayerListener mPlayerEventListener;
 
-    /*----------------------------第一部分:视频初始化实例对象方法----------------------------------*/
-    /**
-     * 初始化播放器实例
-     * 视频播放器第一步:创建视频播放器
-     */
-    public abstract void initPlayer();
-
-    /**
-     * 设置播放地址
-     * 视频播放器第二步:设置数据
-     * @param path    播放地址
-     * @param headers 播放地址请求头
-     */
-    public abstract void setDataSource(String path, Map<String, String> headers);
-
-    /**
-     * 用于播放raw和asset里面的视频文件
-     */
-    public abstract void setDataSource(AssetFileDescriptor fd);
-
-    /**
-     * 设置渲染视频的View,主要用于TextureView
-     * 视频播放器第三步:设置surface
-     * @param surface                           surface
-     */
-    public abstract void setSurface(Surface surface);
-
-    /**
-     * 准备开始播放(异步)
-     * 视频播放器第四步:开始加载【异步】
-     */
-    public abstract void prepareAsync();
-
-    /*----------------------------第二部分:视频播放器状态方法----------------------------------*/
-
-    /**
-     * 播放
-     */
-    public abstract void start();
-
-    /**
-     * 暂停
-     */
-    public abstract void pause();
-
-    /**
-     * 停止
-     */
-    public abstract void stop();
-
-    /**
-     * 重置播放器
-     */
-    public abstract void reset();
-
-    /**
-     * 是否正在播放
-     * @return                                  是否正在播放
-     */
-    public abstract boolean isPlaying();
-
-    /**
-     * 调整进度
-     */
-    public abstract void seekTo(long time);
-
-    /**
-     * 释放播放器
-     */
-    public abstract void release();
-
-    /**
-     * 获取当前播放的位置
-     * @return                                  获取当前播放的位置
-     */
-    public abstract long getCurrentPosition();
-
-    /**
-     * 获取视频总时长
-     * @return                                  获取视频总时长
-     */
-    public abstract long getDuration();
-
-    /**
-     * 获取缓冲百分比
-     * @return                                  获取缓冲百分比
-     */
-    public abstract int getBufferedPercentage();
-
-    /**
-     * 设置渲染视频的View,主要用于SurfaceView
-     * @param holder                            holder
-     */
-    public abstract void setDisplay(SurfaceHolder holder);
-
-    /**
-     * 设置音量
-     * @param v1                                v1
-     * @param v2                                v2
-     */
-    public abstract void setVolume(float v1, float v2);
-
-    /**
-     * 设置是否循环播放
-     * @param isLooping                         布尔值
-     */
-    public abstract void setLooping(boolean isLooping);
-
-    /**
-     * 设置其他播放配置
-     */
-    public abstract void setOptions();
-
-    /**
-     * 设置播放速度
-     * @param speed                             速度
-     */
-    public abstract void setSpeed(float speed);
-
-    /**
-     * 获取播放速度
-     * @return                                  播放速度
-     */
-    public abstract float getSpeed();
-
-    /**
-     * 获取当前缓冲的网速
-     * @return                                  获取网络
-     */
-    public abstract long getTcpSpeed();
-
     /*----------------------------第三部分:player绑定view后,需要监听播放状态--------------------*/
 
     /**

+ 129 - 0
VideoKernel/src/main/java/com/yc/kernel/inter/InterBasePlayer.java

@@ -0,0 +1,129 @@
+/*
+Copyright 2017 yangchong211(github.com/yangchong211)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package com.yc.kernel.inter;
+
+import android.view.SurfaceHolder;
+
+/**
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2018/11/9
+ *     desc  : 播放器状态总接口【拓展成视频播放器和音频播放器lib的公共接口】
+ *     revise:
+ * </pre>
+ */
+public interface InterBasePlayer {
+
+    /*----------------------------第二部分:视频播放器状态方法----------------------------------*/
+
+    /**
+     * 播放
+     */
+    void start();
+
+    /**
+     * 暂停
+     */
+    void pause();
+
+    /**
+     * 停止
+     */
+    void stop();
+
+    /**
+     * 重置播放器
+     */
+    void reset();
+
+    /**
+     * 是否正在播放
+     * @return                                  是否正在播放
+     */
+    boolean isPlaying();
+
+    /**
+     * 调整进度
+     */
+    void seekTo(long time);
+
+    /**
+     * 释放播放器
+     */
+    void release();
+
+    /**
+     * 获取当前播放的位置
+     * @return                                  获取当前播放的位置
+     */
+    long getCurrentPosition();
+
+    /**
+     * 获取视频总时长
+     * @return                                  获取视频总时长
+     */
+    long getDuration();
+
+    /**
+     * 获取缓冲百分比
+     * @return                                  获取缓冲百分比
+     */
+    int getBufferedPercentage();
+
+    /**
+     * 设置渲染视频的View,主要用于SurfaceView
+     * @param holder                            holder
+     */
+    void setDisplay(SurfaceHolder holder);
+
+    /**
+     * 设置音量
+     * @param v1                                v1
+     * @param v2                                v2
+     */
+    void setVolume(float v1, float v2);
+
+    /**
+     * 设置是否循环播放
+     * @param isLooping                         布尔值
+     */
+    void setLooping(boolean isLooping);
+
+    /**
+     * 设置其他播放配置
+     */
+    void setOptions();
+
+    /**
+     * 设置播放速度
+     * @param speed                             速度
+     */
+    void setSpeed(float speed);
+
+    /**
+     * 获取播放速度
+     * @return                                  播放速度
+     */
+    float getSpeed();
+
+    /**
+     * 获取当前缓冲的网速
+     * @return                                  获取网络
+     */
+    long getTcpSpeed();
+
+}

+ 70 - 0
VideoKernel/src/main/java/com/yc/kernel/inter/InterInitPlayer.java

@@ -0,0 +1,70 @@
+/*
+Copyright 2017 yangchong211(github.com/yangchong211)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package com.yc.kernel.inter;
+
+import android.content.res.AssetFileDescriptor;
+import android.view.Surface;
+
+import java.util.Map;
+
+/**
+ * <pre>
+ *     @author yangchong
+ *     blog  : https://github.com/yangchong211
+ *     time  : 2018/11/9
+ *     desc  : 播放器初始化总接口【拓展成视频播放器和音频播放器lib的公共接口】
+ *     revise:
+ * </pre>
+ */
+public interface InterInitPlayer {
+
+    /*----------------------------第一部分:视频初始化实例对象方法----------------------------------*/
+
+
+    /**
+     * 初始化播放器实例
+     * 视频播放器第一步:创建视频播放器
+     */
+    void initPlayer();
+
+    /**
+     * 设置播放地址
+     * 视频播放器第二步:设置数据
+     * @param path    播放地址
+     * @param headers 播放地址请求头
+     */
+    void setDataSource(String path, Map<String, String> headers);
+
+    /**
+     * 用于播放raw和asset里面的视频文件
+     */
+    void setDataSource(AssetFileDescriptor fd);
+
+    /**
+     * 设置渲染视频的View,主要用于TextureView
+     * 视频播放器第三步:设置surface
+     * @param surface                           surface
+     */
+    void setSurface(Surface surface);
+
+    /**
+     * 准备开始播放(异步)
+     * 视频播放器第四步:开始加载【异步】
+     */
+    void prepareAsync();
+
+
+}