surfaceview+mediaplayerview实现本地网络视频播放

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jhl122/article/details/76491178

GitHub地址:https://github.com/JiangAndroidwork/MyMediaPlayer

具体的代码请在github上面查看,我主要记录一下踩过的坑,需要注意的地方。

  1. 需要注意的SurfaceHolder.getHolder.addCallback(this)的回调方法surfaceCreated()、surfaceDestoryed()生命周期,surfaceCreated()是初始化的时候加载的,mediaplayerview也是在这个方法内进行创建。当手机按home键返回桌面的时候会调用 surfaceDestoryed()方法,当再点击应用进入播放页面的时候会再次调用surfaceCreated方法,所以有的时候要注意避免方法的重复调用,当再次进入应用的时候要判断mediplayer是否为null,如果为null就是第一次进入执行创建方法,当不为null的时候就不需要创建mediaplayer,直接执行seekTo() 和start()方法即可。
  2. 有关Timer 和TimerTask的使用,我是用Timer来实时更新播放的进度条和时间显示,所以在使用的时候要注意timer的创建和cancel,当执行surfaceDestoryed()或者退出界面的时候需要及时的cancel并且将timer置为null,释放资源,也为了保证不出现异
  3. 在mediaplayer的prepera方法完成之前最好不要点击播放按钮和进度条,所以就要设定setEnable(false),当完成了之后再setEnable(true)。但是有一个问题,那就是surfaceHolder.callBack(this)回调方法surfaceCreated(),当点击home回到桌面 再点击进入应用还是会调用这个方法的,所以 设定不能点击的方法不能放在surfaceCreated()里面,就会导致每次onResume的时候按钮还是不能点击,因为一般是先调用onResume然后才是surfaceCreated()方法。
  4. 网速显示实现原理:获取应用当前使用的流量大小减去1秒之前的流量大小除以这个时间差就是 单位时间的网速。

    public class InternetUtils {
    
        /**
         * 获取流量
         * @param context
         * @return
         */
        public static long getInternetSpeed(Context context){
            long l = 0;
            PackageManager pm = context.getPackageManager();
            try {
                ApplicationInfo ai = pm.getApplicationInfo(context.getPackageName(), PackageManager.GET_ACTIVITIES);
                //转为KB
                l = TrafficStats.getUidRxBytes(ai.uid) == TrafficStats.UNSUPPORTED ? 0 : (TrafficStats.getTotalRxBytes() / 1024);
    
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
    
            }
            return l;
        }
    
    
    }
    

    /**
         * 显示网速
         */
        private void showSpeed() {
            long nowTotalRxBytes = InternetUtils.getInternetSpeed(context);
            long nowTimeStamp = System.currentTimeMillis();
            long speed = ((nowTotalRxBytes - lastTotalRxBytes) * 1000 / (nowTimeStamp - lastTimeStamp));//毫秒转换
    
            lastTimeStamp = nowTimeStamp;
            lastTotalRxBytes = nowTotalRxBytes;
    
            Message msg = handler.obtainMessage();
            msg.what = 100;
    
            if (speed<1){
                msg.obj = String.valueOf(speed*1024)+"B/s";
            }else if (speed>=1024){
                msg.obj = String.valueOf((float) speed/1024).substring(0,3)+"Mb/s";
            }else {
                msg.obj = String.valueOf(speed) + " kb/s";
            }
    
            handler.sendMessage(msg);//更新界面
        }
  5. 缓冲百分比的实现
    首先mediaplayer有个监听方法用来实现整个视频的缓冲百分比:setOnBufferingUpdateListener(this),我是自己设定一个充盈区z,用缓冲好的部分减去当前播放的位置得出的大小 y 和充盈区去比较,当大于充盈区的时候就不用缓冲直接播放,当小于缓冲区的时候直接暂停缓冲,并且缓冲百分比 x 直接用:y/100% = y/x 得出实时的百分比。

     @Override
        public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
            mediaplayerPercentage = i;
            setLoadingValue = (float) (videoLength * 0.07);//设置充盈区百分比为百分之7
            currentPosition = mediaPlayer.getCurrentPosition();
            mediaplayerLoading = (videoLength * i) / 100;
            y = mediaplayerLoading - currentPosition;
            if (y < setLoadingValue) {//如果差值小于 设定的缓存值 则是缓冲状态
                //当 mediaplayer的缓冲百分比为100%时就不用考虑自定义缓冲进度,直接隐藏直接显示按钮
                if (i==100){
                    if (this.getVisibility()==GONE) {this.setVisibility(VISIBLE);}
                    if (ivPlayer.getVisibility()==GONE) ivPlayer.setVisibility(VISIBLE);
                    if (tvShowPercentage.getVisibility()==VISIBLE) tvShowPercentage.setVisibility(GONE);
                    if (progressBar.getVisibility()==VISIBLE) progressBar.setVisibility(GONE);
                    if (tvInternetSpeed.getVisibility()==VISIBLE) tvInternetSpeed.setVisibility(GONE);
                }else {
                    initLoading();
    
                }
            } else if (y>=setLoadingValue&&PlayerContent.PLAY_STATE==1){
    
                initPause();
    
            }else if (PlayerContent.PLAY_STATE==0){
                initPlaying();
            }
            float v =  (currentPosition / videoLength);
            percentageOfLoading = (int) ((100*y)/setLoadingValue);
    
            if (percentageOfLoading>100){
                percentageOfLoading=100;
            }else if (percentageOfLoading<0){
                percentageOfLoading = 0;
            }
    
            tvShowPercentage.setText(percentageOfLoading +"%");
    //        Log.i(TAG,"已经缓冲的大小=="+i+"\n"+"视频播放的百分比=="+v+"\n"+"设置的缓冲百分比=="+7);
            initShowOrHind();
        }
  6. 要注意mediaplayerview的一些状态 避免出现异常,比如,只有当prepared成功回调之后才能 start(),当播放完了之后要released()回收资源http://blog.csdn.net/u014434080/article/details/71305727



猜你喜欢

转载自blog.csdn.net/jhl122/article/details/76491178