IjkVideoView

package com.dou361.ijkplayer.widget;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.MediaController;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import tv.danmaku.ijk.media.player.AndroidMediaPlayer;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;
import tv.danmaku.ijk.media.player.TextureMediaPlayer;
import tv.danmaku.ijk.media.player.misc.IMediaDataSource;

/**
 * ========================================
 * <p>
 * 版 权:dou361.com 版权所有 (C) 2015
 * <p>
 * 作 者:陈冠明
 * <p>
 * 个人网站:http://www.dou361.com
 * <p>
 * 版 本:1.0
 * <p>
 * 创建日期:2016/8/10 15:29
 * <p>
 * 描 述:视频渲染界面管理
 * <p>
 * <p>
 * 修订历史:
 * <p>
 * ========================================
 */
public class IjkVideoView extends FrameLayout implements MediaController.MediaPlayerControl {
    private String TAG = this.getClass().getSimpleName();
    /**
     * settable by the client  播放地址通过客户端可设置
     */
    private Uri mUri;
    /**
     * 播放器的一些基本配置
     */
    private Map<String, String> mHeaders;

    /**
     * mCurrentState is a VideoView object's current state.
     * mTargetState is the state that a method caller intends to reach.
     * For instance, regardless the VideoView object's current state,
     * calling pause() intends to bring the object to a target state
     * of STATE_PAUSED.
     */
    private int mCurrentState = PlayStateParams.STATE_IDLE;
    private int mTargetState = PlayStateParams.STATE_IDLE;

    /**
     * All the stuff we need for playing and showing a video 所有的东西我们需要播放和显示视频
     */
    private IRenderView.ISurfaceHolder mSurfaceHolder = null;
    /**
     * 视频宽度
     */
    private int mVideoWidth;
    /**
     * 视频高度
     */
    private int mVideoHeight;
    /**
     * 窗口宽度
     */
    private int mSurfaceWidth;
    /**
     * 窗口高度
     */
    private int mSurfaceHeight;
    /**
     * 视频旋转角度
     */
    private int mVideoRotationDegree;
    /**
     * 媒体播放器
     */
    private IMediaPlayer mMediaPlayer;
    /**
     * 媒体控制器
     */
    private IMediaController mMediaController;
    /**
     * 播放完成监听
     */
    private IMediaPlayer.OnCompletionListener mOnCompletionListener;
    /**
     * 播放准备监听
     */
    private IMediaPlayer.OnPreparedListener mOnPreparedListener;
    /**
     * 播放缓冲监听
     */
    private int mCurrentBufferPercentage;
    /**
     * 播放错误监听
     */
    private IMediaPlayer.OnErrorListener mOnErrorListener;
    /**
     * 播放其他信息监听
     */
    private IMediaPlayer.OnInfoListener mOnInfoListener;
    /**
     * recording the seek position while preparing 记录寻求位置而做准备
     */
    private long mSeekWhenPrepared;
    /**
     * 是否可以暂停
     */
    private boolean mCanPause = true;

    /** Subtitle rendering widget overlaid on top of the video. */
    // private RenderingWidget mSubtitleWidget;

    /**
     * Listener for changes to subtitle data, used to redraw when needed.
     */
    // private RenderingWidget.OnChangedListener mSubtitlesChangedListener;

    private Context mAppContext;
    private IRenderView mRenderView;
    private int mVideoSarNum;
    private int mVideoSarDen;
    /**
     * 使用Android播放器
     */
    private boolean usingAndroidPlayer = false;
    /**
     * 使用编解码器硬编码还是软编码,true 硬编码 false 为软编码
     */
    private boolean usingMediaCodec = false;
    /**
     * 使用编解码是否自转
     */
    private boolean usingMediaCodecAutoRotate = false;
    private boolean usingOpenSLES = false;
    /**
     * Auto Select=,RGB 565=fcc-rv16,RGB 888X=fcc-rv32,YV12=fcc-yv12,默认为RGB 888X
     */
    private String pixelFormat = "";//Auto Select=,RGB 565=fcc-rv16,RGB 888X=fcc-rv32,YV12=fcc-yv12,默认为RGB 888X
    private boolean enableBackgroundPlay = false;

    public IjkVideoView(Context context) {
        super(context);
        initVideoView(context);
    }

    public IjkVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initVideoView(context);
    }

    public IjkVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initVideoView(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public IjkVideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initVideoView(context);
    }

    // REMOVED: onMeasure
    // REMOVED: onInitializeAccessibilityEvent
    // REMOVED: onInitializeAccessibilityNodeInfo
    // REMOVED: resolveAdjustedSize

    /**
     * 初始化视频view
     */
    private void initVideoView(Context context) {
        mAppContext = context.getApplicationContext();

        initBackground();
        initRenders();

        mVideoWidth = 0;
        mVideoHeight = 0;
        // REMOVED: getHolder().addCallback(mSHCallback);
        // REMOVED: getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        /** 设置为可触摸并且获取焦点 */
        setFocusable(true);
        setFocusableInTouchMode(true);
        requestFocus();
        // REMOVED: mPendingSubtitleTracks = new Vector<Pair<InputStream, MediaFormat>>();
        mCurrentState = PlayStateParams.STATE_IDLE;
        mTargetState = PlayStateParams.STATE_IDLE;
    }

    /**
     * 设置渲染器
     */
    public void setRenderView(IRenderView renderView) {
        if (mRenderView != null) {
            if (mMediaPlayer != null)
                mMediaPlayer.setDisplay(null);

            View renderUIView = mRenderView.getView();
            mRenderView.removeRenderCallback(mSHCallback);
            mRenderView = null;
            removeView(renderUIView);
        }

        if (renderView == null)
            return;

        mRenderView = renderView;
        renderView.setAspectRatio(mCurrentAspectRatio);
        if (mVideoWidth > 0 && mVideoHeight > 0)
            renderView.setVideoSize(mVideoWidth, mVideoHeight);
        if (mVideoSarNum > 0 && mVideoSarDen > 0)
            renderView.setVideoSampleAspectRatio(mVideoSarNum, mVideoSarDen);

        View renderUIView = mRenderView.getView();
        /**修复一个bug,宽度不填满问题,感谢热心兄弟的慧眼*/
        LayoutParams lp = new LayoutParams(
                LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT,
                Gravity.CENTER);
        renderUIView.setLayoutParams(lp);
        addView(renderUIView);

        mRenderView.addRenderCallback(mSHCallback);
        mRenderView.setVideoRotation(mVideoRotationDegree);
    }

    /**
     * 设置旋转角度
     */
    public void setPlayerRotation(int rotation) {
        mVideoRotationDegree = rotation;
        if (mRenderView != null) {
            mRenderView.setVideoRotation(mVideoRotationDegree);
        }
    }

    /**
     * 旋转渲染器
     */
    public void setRender(int render) {
        switch (render) {
            case RENDER_TEXTURE_VIEW: {
                TextureRenderView renderView = new Te
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值