美文网首页android
JiaoZiVideoPlayer饺子视频播放器在部分手机不兼容

JiaoZiVideoPlayer饺子视频播放器在部分手机不兼容

作者: 因为我的心 | 来源:发表于2019-11-19 18:32 被阅读0次

    一、前言:

    在使用饺子视频的时候,在部分安卓手机不兼容,比如,金立手机,华为部分手机,一直显示加载框,不能播放视频。
    demo地址:https://github.com/lipangit/JiaoZiVideoPlayer

    1. 引包

    implementation 'cn.jzvd:jiaozivideoplayer:6.2.12'
    

    或者下载lib(不推荐)。
    (https://github.com/lipangit/JiaoZiVideoPlayer/releases/tag/v6.2.12) (not recommended).

    2. 添加JZVideoPlayer你的布局:

    <cn.jzvd.JZVideoPlayerStandard
        android:id="@+id/videoplayer"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>
    

    3. 设置视频uri,视频拇指网址和视频标题:

    JZVideoPlayerStandard jzVideoPlayerStandard = (JZVideoPlayerStandard) findViewById(R.id.videoplayer);
     // 图片等比例放大
     jzVideoPlayerStandard .thumbImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    
    //设置视频裁剪方式(导致部分页面被裁切)
    //Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_SCROP);
     //设置容器内播放器高(能完整显示)
    Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_PARENT);
    
    jzVideoPlayerStandard.setUp("http://jzvd.nathen.cn/c6e3dc12a1154626b3476d9bf3bd7266/6b56c5f0dc31428083757a45764763b0-5287d2089db37e62345123a1be272f8b.mp4",   "饺子闭眼睛",
                                JZVideoPlayerStandard.SCREEN_WINDOW_NORMAL
                              );
    jzVideoPlayerStandard.thumbImageView.setImage("http://p.qpic.cn/videoyun/0/2449_43b6f696980311e59ed467f22794e792_1/640");
    
    
    

    4.在 Activity:

    @Override
    public void onBackPressed() {
        if (JZVideoPlayer.backPress()) {
            return;
        }
        super.onBackPressed();
    }
    @Override
    protected void onPause() {
        super.onPause();
        JZVideoPlayer.releaseAllVideos();
    }
    

    5. 在 AndroidManifest.xml:(清单文件)

    <activity
        android:name=".MainActivity"
        android:configChanges="orientation|screenSize|keyboardHidden"
        android:screenOrientation="portrait" />
        <!-- or android:screenOrientation="landscape"-->
    

    二、解决部分手机不兼容(更换bilibili内核):

    方式:通过更换饺子视频播放内核就可以了。

    注意:bilibili内核不支持https视频链接。

    1. 引入bilibili内核

        implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
        implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'
        implementation 'cn.jzvd:jiaozivideoplayer:6.2.12'
    

    2. 更换内核

    bilibili内核: JZMediaIjk.class

     // 这个播放地址有问题
     "https://sumansoul.oss-cn-shanghai.aliyuncs.com/admin/video/XdPTxKFjH28Xhc7BWWxrnnwmBRt7x8mH.mp4";
    
    JZVideoPlayerStandard jzVideoPlayerStandard = (JZVideoPlayerStandard) findViewById(R.id.videoplayer);
     // 图片等比例放大
     jzVideoPlayerStandard .thumbImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    
    //设置视频裁剪方式(导致部分页面被裁切)
    //Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_SCROP);
     //设置容器内播放器高(能完整显示)
    Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_PARENT);
    
    jzVideoPlayerStandard.setUp("http://jzvd.nathen.cn/c6e3dc12a1154626b3476d9bf3bd7266/6b56c5f0dc31428083757a45764763b0-5287d2089db37e62345123a1be272f8b.mp4",  "饺子闭眼睛" , 
                                JZVideoPlayerStandard.SCREEN_WINDOW_NORMAL, 
                               JZMediaIjk.class);
    jzVideoPlayerStandard.thumbImageView.setImage("http://p.qpic.cn/videoyun/0/2449_43b6f696980311e59ed467f22794e792_1/640");
    
    

    2. JZMediaIjk文件:

    package com.sumansoul.student.widget.video;
    
    import android.graphics.SurfaceTexture;
    import android.media.AudioManager;
    import android.os.Handler;
    import android.os.HandlerThread;
    import android.view.Surface;
    
    import java.io.IOException;
    
    import cn.jzvd.JZMediaInterface;
    import cn.jzvd.Jzvd;
    import tv.danmaku.ijk.media.player.IMediaPlayer;
    import tv.danmaku.ijk.media.player.IjkMediaPlayer;
    import tv.danmaku.ijk.media.player.IjkTimedText;
    
    /**
     *
     * Created by Nathen on 2017/11/18.
     */
    
    public class JZMediaIjk extends JZMediaInterface implements IMediaPlayer.OnPreparedListener, IMediaPlayer.OnVideoSizeChangedListener, IMediaPlayer.OnCompletionListener, IMediaPlayer.OnErrorListener, IMediaPlayer.OnInfoListener, IMediaPlayer.OnBufferingUpdateListener, IMediaPlayer.OnSeekCompleteListener, IMediaPlayer.OnTimedTextListener {
        IjkMediaPlayer ijkMediaPlayer;
    
        public JZMediaIjk(Jzvd jzvd) {
            super(jzvd);
        }
    
        @Override
        public void start() {
            if (ijkMediaPlayer != null) ijkMediaPlayer.start();
        }
    
        @Override
        public void prepare() {
    
            release();
            mMediaHandlerThread = new HandlerThread("JZVD");
            mMediaHandlerThread.start();
            mMediaHandler = new Handler(mMediaHandlerThread.getLooper());//主线程还是非主线程,就在这里
            handler = new Handler();
    
            mMediaHandler.post(() -> {
    
                ijkMediaPlayer = new IjkMediaPlayer();
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 0);
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 0);
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0);
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", 1024 * 1024);
                ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);
    
                ijkMediaPlayer.setOnPreparedListener(JZMediaIjk.this);
                ijkMediaPlayer.setOnVideoSizeChangedListener(JZMediaIjk.this);
                ijkMediaPlayer.setOnCompletionListener(JZMediaIjk.this);
                ijkMediaPlayer.setOnErrorListener(JZMediaIjk.this);
                ijkMediaPlayer.setOnInfoListener(JZMediaIjk.this);
                ijkMediaPlayer.setOnBufferingUpdateListener(JZMediaIjk.this);
                ijkMediaPlayer.setOnSeekCompleteListener(JZMediaIjk.this);
                ijkMediaPlayer.setOnTimedTextListener(JZMediaIjk.this);
    
                try {
                    ijkMediaPlayer.setDataSource(jzvd.jzDataSource.getCurrentUrl().toString());
                    ijkMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    ijkMediaPlayer.setScreenOnWhilePlaying(true);
                    ijkMediaPlayer.prepareAsync();
    
                    ijkMediaPlayer.setSurface(new Surface(jzvd.textureView.getSurfaceTexture()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
    
        }
    
        @Override
        public void pause() {
            ijkMediaPlayer.pause();
        }
    
        @Override
        public boolean isPlaying() {
            return ijkMediaPlayer.isPlaying();
        }
    
        @Override
        public void seekTo(long time) {
            ijkMediaPlayer.seekTo(time);
        }
    
        @Override
        public void release() {
            if (mMediaHandler != null && mMediaHandlerThread != null && ijkMediaPlayer != null) {//不知道有没有妖孽
                HandlerThread tmpHandlerThread = mMediaHandlerThread;
                IjkMediaPlayer tmpMediaPlayer = ijkMediaPlayer;
                JZMediaInterface.SAVED_SURFACE = null;
    
                mMediaHandler.post(() -> {
                    tmpMediaPlayer.setSurface(null);
                    tmpMediaPlayer.release();
                    tmpHandlerThread.quit();
                });
                ijkMediaPlayer = null;
            }
        }
    
        @Override
        public long getCurrentPosition() {
            return ijkMediaPlayer.getCurrentPosition();
        }
    
        @Override
        public long getDuration() {
            return ijkMediaPlayer.getDuration();
        }
    
        @Override
        public void setVolume(float leftVolume, float rightVolume) {
            ijkMediaPlayer.setVolume(leftVolume, rightVolume);
        }
    
        @Override
        public void setSpeed(float speed) {
            ijkMediaPlayer.setSpeed(speed);
        }
    
        @Override
        public void onPrepared(IMediaPlayer iMediaPlayer) {
            handler.post(() -> jzvd.onPrepared());
        }
    
        @Override
        public void onVideoSizeChanged(IMediaPlayer iMediaPlayer, int i, int i1, int i2, int i3) {
            handler.post(() -> jzvd.onVideoSizeChanged(iMediaPlayer.getVideoWidth(), iMediaPlayer.getVideoHeight()));
        }
    
        @Override
        public boolean onError(IMediaPlayer iMediaPlayer, final int what, final int extra) {
            handler.post(() -> jzvd.onError(what, extra));
            return true;
        }
    
        @Override
        public boolean onInfo(IMediaPlayer iMediaPlayer, final int what, final int extra) {
            handler.post(() -> jzvd.onInfo(what, extra));
            return false;
        }
    
        @Override
        public void onBufferingUpdate(IMediaPlayer iMediaPlayer, final int percent) {
            handler.post(() -> jzvd.setBufferProgress(percent));
        }
    
        @Override
        public void onSeekComplete(IMediaPlayer iMediaPlayer) {
            handler.post(() -> jzvd.onSeekComplete());
        }
    
        @Override
        public void onTimedText(IMediaPlayer iMediaPlayer, IjkTimedText ijkTimedText) {
    
        }
    
        @Override
        public void setSurface(Surface surface) {
            ijkMediaPlayer.setSurface(surface);
        }
    
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            if (SAVED_SURFACE == null) {
                SAVED_SURFACE = surface;
                prepare();
            } else {
                jzvd.textureView.setSurfaceTexture(SAVED_SURFACE);
            }
        }
    
        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    
        }
    
        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            return false;
        }
    
        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    
        }
    
        @Override
        public void onCompletion(IMediaPlayer iMediaPlayer) {
            handler.post(() -> jzvd.onAutoCompletion());
        }
    }
    

    三、解决部分手机不兼容(更换exoplayer内核):

    方式:通过更换饺子视频播放内核就可以了。

    1. 引入exoplayer内核

      implementation 'com.google.android.exoplayer:exoplayer:2.9.1'
      implementation 'cn.jzvd:jiaozivideoplayer:6.2.12'
    

    2. 更换内核

    exoplayer内核: JZMediaExo.class

     // 这个播放地址有问题
     "https://sumansoul.oss-cn-shanghai.aliyuncs.com/admin/video/XdPTxKFjH28Xhc7BWWxrnnwmBRt7x8mH.mp4";
    
    JZVideoPlayerStandard jzVideoPlayerStandard = (JZVideoPlayerStandard) findViewById(R.id.videoplayer);
     // 图片等比例放大
     jzVideoPlayerStandard .thumbImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    
    //设置视频裁剪方式(导致部分页面被裁切)
    //Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_SCROP);
     //设置容器内播放器高(能完整显示)
    Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_PARENT);
    
    jzVideoPlayerStandard.setUp("http://jzvd.nathen.cn/c6e3dc12a1154626b3476d9bf3bd7266/6b56c5f0dc31428083757a45764763b0-5287d2089db37e62345123a1be272f8b.mp4",  "饺子闭眼睛" , 
                                JZVideoPlayerStandard.SCREEN_WINDOW_NORMAL, 
                               JZMediaExo.class);
    jzVideoPlayerStandard.thumbImageView.setImage("http://p.qpic.cn/videoyun/0/2449_43b6f696980311e59ed467f22794e792_1/640");
    
    

    2. JZMediaExo文件:

    /**
     * Created by MinhDV on 5/3/18.
     */
    public class JZMediaExo extends JZMediaInterface implements Player.EventListener, VideoListener {
        private SimpleExoPlayer simpleExoPlayer;
        private Runnable callback;
        private String TAG = "JZMediaExo";
        private long previousSeek = 0;
    
        public JZMediaExo(Jzvd jzvd) {
            super(jzvd);
        }
    
        @Override
        public void start() {
            simpleExoPlayer.setPlayWhenReady(true);
        }
    
        @Override
        public void prepare() {
            Log.e(TAG, "prepare");
            Context context = jzvd.getContext();
    
            release();
            mMediaHandlerThread = new HandlerThread("JZVD");
            mMediaHandlerThread.start();
            mMediaHandler = new Handler(mMediaHandlerThread.getLooper());//主线程还是非主线程,就在这里
            handler = new Handler();
            mMediaHandler.post(() -> {
                BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
                TrackSelection.Factory videoTrackSelectionFactory =
                        new AdaptiveTrackSelection.Factory(bandwidthMeter);
                TrackSelector trackSelector =
                        new DefaultTrackSelector(videoTrackSelectionFactory);
    
                LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE),
                        360000, 600000, 1000, 5000,
                        C.LENGTH_UNSET,
                        false);
    
                // 2. Create the player
    
                RenderersFactory renderersFactory = new DefaultRenderersFactory(context);
                simpleExoPlayer = ExoPlayerFactory.newSimpleInstance(context, renderersFactory, trackSelector, loadControl);
                // Produces DataSource instances through which media data is loaded.
                DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context,
                        Util.getUserAgent(context, context.getResources().getString(R.string.app_name)));
    
                String currUrl = jzvd.jzDataSource.getCurrentUrl().toString();
                MediaSource videoSource;
                if (currUrl.contains(".m3u8")) {
                    videoSource = new HlsMediaSource.Factory(dataSourceFactory)
                            .createMediaSource(Uri.parse(currUrl), handler, null);
                } else {
                    videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
                            .createMediaSource(Uri.parse(currUrl));
                }
                simpleExoPlayer.addVideoListener(this);
    
                Log.e(TAG, "URL Link = " + currUrl);
    
                simpleExoPlayer.addListener(this);
                Boolean isLoop = jzvd.jzDataSource.looping;
                if (isLoop) {
                    simpleExoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);
                } else {
                    simpleExoPlayer.setRepeatMode(Player.REPEAT_MODE_OFF);
                }
                simpleExoPlayer.prepare(videoSource);
                simpleExoPlayer.setPlayWhenReady(true);
                callback = new onBufferingUpdate();
    
                simpleExoPlayer.setVideoSurface(new Surface(jzvd.textureView.getSurfaceTexture()));
            });
    
        }
    
        @Override
        public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
            handler.post(() -> jzvd.onVideoSizeChanged(width, height));
        }
    
        @Override
        public void onRenderedFirstFrame() {
            Log.e(TAG, "onRenderedFirstFrame");
        }
    
        @Override
        public void pause() {
            simpleExoPlayer.setPlayWhenReady(false);
        }
    
        @Override
        public boolean isPlaying() {
            return simpleExoPlayer.getPlayWhenReady();
        }
    
        @Override
        public void seekTo(long time) {
            if (time != previousSeek) {
                simpleExoPlayer.seekTo(time);
                previousSeek = time;
                jzvd.seekToInAdvance = time;
            }
        }
    
        @Override
        public void release() {
            if (mMediaHandler != null && mMediaHandlerThread != null && simpleExoPlayer != null) {//不知道有没有妖孽
                HandlerThread tmpHandlerThread = mMediaHandlerThread;
                SimpleExoPlayer tmpMediaPlayer = simpleExoPlayer;
                JZMediaInterface.SAVED_SURFACE = null;
    
                mMediaHandler.post(() -> {
                    tmpMediaPlayer.release();//release就不能放到主线程里,界面会卡顿
                    tmpHandlerThread.quit();
                });
                simpleExoPlayer = null;
            }
        }
    
        @Override
        public long getCurrentPosition() {
            if (simpleExoPlayer != null)
                return simpleExoPlayer.getCurrentPosition();
            else return 0;
        }
    
        @Override
        public long getDuration() {
            if (simpleExoPlayer != null)
                return simpleExoPlayer.getDuration();
            else return 0;
        }
    
        @Override
        public void setVolume(float leftVolume, float rightVolume) {
            simpleExoPlayer.setVolume(leftVolume);
            simpleExoPlayer.setVolume(rightVolume);
        }
    
        @Override
        public void setSpeed(float speed) {
            PlaybackParameters playbackParameters = new PlaybackParameters(speed, 1.0F);
            simpleExoPlayer.setPlaybackParameters(playbackParameters);
        }
    
        @Override
        public void onTimelineChanged(final Timeline timeline, Object manifest, final int reason) {
            Log.e(TAG, "onTimelineChanged");
    //        JZMediaPlayer.instance().mainThreadHandler.post(() -> {
    //                if (reason == 0) {
    //
    //                    JzvdMgr.getCurrentJzvd().onInfo(reason, timeline.getPeriodCount());
    //                }
    //        });
        }
    
        @Override
        public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
    
        }
    
        @Override
        public void onLoadingChanged(boolean isLoading) {
            Log.e(TAG, "onLoadingChanged");
        }
    
        @Override
        public void onPlayerStateChanged(final boolean playWhenReady, final int playbackState) {
            Log.e(TAG, "onPlayerStateChanged" + playbackState + "/ready=" + String.valueOf(playWhenReady));
            handler.post(() -> {
                switch (playbackState) {
                    case Player.STATE_IDLE: {
                    }
                    break;
                    case Player.STATE_BUFFERING: {
                        handler.post(callback);
                    }
                    break;
                    case Player.STATE_READY: {
                        if (playWhenReady) {
                            jzvd.onStatePlaying();
                        } else {
                        }
                    }
                    break;
                    case Player.STATE_ENDED: {
                        jzvd.onAutoCompletion();
                    }
                    break;
                }
            });
        }
    
        @Override
        public void onRepeatModeChanged(int repeatMode) {
    
        }
    
        @Override
        public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
    
        }
    
        @Override
        public void onPlayerError(ExoPlaybackException error) {
            Log.e(TAG, "onPlayerError" + error.toString());
            handler.post(() -> jzvd.onError(1000, 1000));
        }
    
        @Override
        public void onPositionDiscontinuity(int reason) {
    
        }
    
        @Override
        public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
    
        }
    
        @Override
        public void onSeekProcessed() {
            handler.post(() -> jzvd.onSeekComplete());
        }
    
        @Override
        public void setSurface(Surface surface) {
            simpleExoPlayer.setVideoSurface(surface);
        }
    
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            if (SAVED_SURFACE == null) {
                SAVED_SURFACE = surface;
                prepare();
            } else {
                jzvd.textureView.setSurfaceTexture(SAVED_SURFACE);
            }
        }
    
        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
    
        }
    
        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            return false;
        }
    
        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    
        }
    
        private class onBufferingUpdate implements Runnable {
            @Override
            public void run() {
                if (simpleExoPlayer != null) {
                    final int percent = simpleExoPlayer.getBufferedPercentage();
                    handler.post(() -> jzvd.setBufferProgress(percent));
                    if (percent < 100) {
                        handler.postDelayed(callback, 300);
                    } else {
                        handler.removeCallbacks(callback);
                    }
                }
            }
        }
    }
    

    四、解决部分手机不兼容(Android系统播放内核):

    1. 引入jar包:

    implementation 'cn.jzvd:jiaozivideoplayer:6.2.12'
    

    2. 更换内核

    系统播放内核: JZMediaSystemAssertFolder.class

     // 这个播放地址有问题
     "https://sumansoul.oss-cn-shanghai.aliyuncs.com/admin/video/XdPTxKFjH28Xhc7BWWxrnnwmBRt7x8mH.mp4";
    
    JZVideoPlayerStandard jzVideoPlayerStandard = (JZVideoPlayerStandard) findViewById(R.id.videoplayer);
     // 图片等比例放大
     jzVideoPlayerStandard .thumbImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    
    //设置视频裁剪方式(导致部分页面被裁切)
    //Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_SCROP);
     //设置容器内播放器高(能完整显示)
    Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_PARENT);
    
    jzVideoPlayerStandard.setUp("http://jzvd.nathen.cn/c6e3dc12a1154626b3476d9bf3bd7266/6b56c5f0dc31428083757a45764763b0-5287d2089db37e62345123a1be272f8b.mp4",  "饺子闭眼睛" , 
                                JZVideoPlayerStandard.SCREEN_WINDOW_NORMAL, 
                               JZMediaSystemAssertFolder.class);
    jzVideoPlayerStandard.thumbImageView.setImage("http://p.qpic.cn/videoyun/0/2449_43b6f696980311e59ed467f22794e792_1/640");
    
    

    2. JZMediaSystemAssertFolder文件:

    /**
     * Created by Nathen on 2017/11/8.
     * 实现系统的播放引擎
     */
    public class JZMediaSystemAssertFolder extends JZMediaInterface implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener, MediaPlayer.OnVideoSizeChangedListener {
    
        public MediaPlayer mediaPlayer;
    
        public JZMediaSystemAssertFolder(Jzvd jzvd) {
            super(jzvd);
        }
    
        @Override
        public void prepare() {
            release();
            mMediaHandlerThread = new HandlerThread("JZVD");
            mMediaHandlerThread.start();
            mMediaHandler = new Handler(mMediaHandlerThread.getLooper());//主线程还是非主线程,就在这里
            handler = new Handler();
    
            mMediaHandler.post(() -> {
                try {
                    mediaPlayer = new MediaPlayer();
                    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                    mediaPlayer.setLooping(jzvd.jzDataSource.looping);
                    mediaPlayer.setOnPreparedListener(JZMediaSystemAssertFolder.this);
                    mediaPlayer.setOnCompletionListener(JZMediaSystemAssertFolder.this);
                    mediaPlayer.setOnBufferingUpdateListener(JZMediaSystemAssertFolder.this);
                    mediaPlayer.setScreenOnWhilePlaying(true);
                    mediaPlayer.setOnSeekCompleteListener(JZMediaSystemAssertFolder.this);
                    mediaPlayer.setOnErrorListener(JZMediaSystemAssertFolder.this);
                    mediaPlayer.setOnInfoListener(JZMediaSystemAssertFolder.this);
                    mediaPlayer.setOnVideoSizeChangedListener(JZMediaSystemAssertFolder.this);
    
                    //two lines are different
                    AssetFileDescriptor assetFileDescriptor = (AssetFileDescriptor) jzvd.jzDataSource.getCurrentUrl();
                    mediaPlayer.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
    
                    mediaPlayer.prepareAsync();
                    mediaPlayer.setSurface(new Surface(jzvd.textureView.getSurfaceTexture()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
    
        @Override
        public void start() {
            mMediaHandler.post(() -> mediaPlayer.start());
        }
    
        @Override
        public void pause() {
            mMediaHandler.post(() -> mediaPlayer.pause());
        }
    
        @Override
        public boolean isPlaying() {
            return mediaPlayer.isPlaying();
        }
    
        @Override
        public void seekTo(long time) {
            mMediaHandler.post(() -> {
                try {
                    mediaPlayer.seekTo((int) time);
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            });
        }
    
        @Override
        public void release() {
            if (mMediaHandler != null && mMediaHandlerThread != null && mediaPlayer != null) {//不知道有没有妖孽
                HandlerThread tmpHandlerThread = mMediaHandlerThread;
                MediaPlayer tmpMediaPlayer = mediaPlayer;
                JZMediaInterface.SAVED_SURFACE = null;
    
                mMediaHandler.post(() -> {
                    tmpMediaPlayer.release();//release就不能放到主线程里,界面会卡顿
                    tmpHandlerThread.quit();
                });
                mediaPlayer = null;
            }
        }
    
        //TODO 测试这种问题是否在threadHandler中是否正常,所有的操作mediaplayer是否不需要thread,挨个测试,是否有问题
        @Override
        public long getCurrentPosition() {
            if (mediaPlayer != null) {
                return mediaPlayer.getCurrentPosition();
            } else {
                return 0;
            }
        }
    
        @Override
        public long getDuration() {
            if (mediaPlayer != null) {
                return mediaPlayer.getDuration();
            } else {
                return 0;
            }
        }
    
        @Override
        public void setVolume(float leftVolume, float rightVolume) {
            if (mMediaHandler == null) return;
            mMediaHandler.post(() -> {
                if (mediaPlayer != null) mediaPlayer.setVolume(leftVolume, rightVolume);
            });
        }
    
        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void setSpeed(float speed) {
            PlaybackParams pp = mediaPlayer.getPlaybackParams();
            pp.setSpeed(speed);
            mediaPlayer.setPlaybackParams(pp);
        }
    
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {
            mediaPlayer.start();
            if (jzvd.jzDataSource.getCurrentUrl().toString().toLowerCase().contains("mp3") ||
                    jzvd.jzDataSource.getCurrentUrl().toString().toLowerCase().contains("wav")) {
                handler.post(() -> jzvd.onPrepared());
            }
        }
    
        @Override
        public void onCompletion(MediaPlayer mediaPlayer) {
            handler.post(() -> jzvd.onAutoCompletion());
        }
    
        @Override
        public void onBufferingUpdate(MediaPlayer mediaPlayer, final int percent) {
            handler.post(() -> jzvd.setBufferProgress(percent));
        }
    
        @Override
        public void onSeekComplete(MediaPlayer mediaPlayer) {
            handler.post(() -> jzvd.onSeekComplete());
        }
    
        @Override
        public boolean onError(MediaPlayer mediaPlayer, final int what, final int extra) {
            handler.post(() -> jzvd.onError(what, extra));
            return true;
        }
    
        @Override
        public boolean onInfo(MediaPlayer mediaPlayer, final int what, final int extra) {
            handler.post(() -> {
                if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
                    if (jzvd.state == Jzvd.STATE_PREPARING
                            || jzvd.state == Jzvd.STATE_PREPARING_CHANGING_URL) {
                        jzvd.onPrepared();
                    }
                } else {
                    jzvd.onInfo(what, extra);
                }
            });
            return false;
        }
    
        @Override
        public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) {
            handler.post(() -> jzvd.onVideoSizeChanged(width, height));
        }
    
        @Override
        public void setSurface(Surface surface) {
            mediaPlayer.setSurface(surface);
        }
    
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
            if (SAVED_SURFACE == null) {
                SAVED_SURFACE = surface;
                prepare();
            } else {
                jzvd.textureView.setSurfaceTexture(SAVED_SURFACE);
            }
        }
    
        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
        }
    
        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
            return false;
        }
    
        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    
        }
    }
    

    五、结尾:

    1. bilibili不支持https链接,可以采用工具生成.so包,可以支持https链接,但是视频加载速度有点慢;
    2. exoplayer内核支持https链接,视频加载速度比较慢;
    3. 可以考虑采用七牛云视频播放器,加载速度飞快,需要二次封装能力;
      4.也可以考虑腾讯云播放器的;

    相关文章

      网友评论

        本文标题:JiaoZiVideoPlayer饺子视频播放器在部分手机不兼容

        本文链接:https://www.haomeiwen.com/subject/sepwictx.html