美文网首页
手机影音03

手机影音03

作者: GeekGray | 来源:发表于2018-10-03 19:20 被阅读9次

    阅读原文

    19-监听播放外界网络和本地视频&如何调起其他播放器

    19.1监听播放外界网络和本地视频,参照Gallery3D代码

     <activity
                android:name="com.atguigu.mobileplayer.video.VideoPlayerActivity"
                android:configChanges="keyboardHidden|screenSize|orientation"
                android:screenOrientation="landscape"
                android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >
                
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
                    <data android:scheme="rtsp" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
    
    
                    <category android:name="android.intent.category.DEFAULT" />
    
    
                    <data android:mimeType="video/*" />
                    <data android:mimeType="application/sdp" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.VIEW" />
    
    
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.BROWSABLE" />
    
    
                    <data android:scheme="http" />
                    <data android:mimeType="video/mpeg4" />
                    <data android:mimeType="video/mp4" />
                    <data android:mimeType="video/3gp" />
                    <data android:mimeType="video/3gpp" />
                    <data android:mimeType="video/3gpp2" />
                </intent-filter>
            </activity>
    

    19.2 加载等待效果

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/bg_player_loading_background"
        android:gravity="center"
        android:orientation="vertical">
    
        <ProgressBar
            android:layout_width="30dp"
            android:layout_height="30dp" />
    
        <TextView
            android:layout_marginTop="3dp"
            android:id="@+id/tv_laoding_netspeed"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:gravity="center"
            android:text="玩命加载中...30kb/s"
            android:textColor="#ffffff"
            android:textSize="10sp" />
    
    </LinearLayout>
    

    播放器控制面板设置为隐藏不可见

    视频播放出来后隐藏加载等待页面

    //隐藏加载页面
    //把加载页面消失掉
            ll_loading.setVisibility(View.GONE);
    

    19.3 解决播放完成后的崩溃

         /**
         * 播放下一个视频
         */
        private void playNextVideo()
        {
            if (mediaItems != null && mediaItems.size() > 0)
            {
                //播放下一个
                position++;
                if (position < mediaItems.size())
                {
                    ll_loading.setVisibility(View.VISIBLE);
                    MediaItem mediaItem = mediaItems.get(position);
                    tvName.setText(mediaItem.getName());
                    isNetUri = utils.isNetUri(mediaItem.getData());
                    videoview.setVideoPath(mediaItem.getData());
    
                    //设置按钮状态
                    setButtonState();
                }
            }
            else if (uri != null)
            {
                //设置按钮状态-上一个和下一个按钮设置灰色并且不可以点击
                setButtonState();
            }
    
        }
    
    /**
         * 播放上一个视频
         */
        private void playPreVideo()
        {
            if (mediaItems != null && mediaItems.size() > 0)
            {
                //播放上一个视频
                position--;
                if (position >= 0)
                {
                    ll_loading.setVisibility(View.VISIBLE);
                    MediaItem mediaItem = mediaItems.get(position);
                    tvName.setText(mediaItem.getName());
                    isNetUri = utils.isNetUri(mediaItem.getData());
                    videoview.setVideoPath(mediaItem.getData());
    
                    //设置按钮状态
                    setButtonState();
                }
            }
            else if (uri != null)
            {
                //设置按钮状态-上一个和下一个按钮设置灰色并且不可以点击
                setButtonState();
            }
        }
    

    19.4 处理播放外界资源的时候,下一个视频按钮和上一个要变灰

    private void setButtonState()
        {
            if (mediaItems != null && mediaItems.size() > 0)
            {
                if (mediaItems.size() == 1)
                {
                    setEnable(false);
                }
                else if (mediaItems.size() == 2)
                {
                    if (position == 0)
                    {
                        btnVideoPre.setBackgroundResource(R.drawable.btn_pre_gray);
                        btnVideoPre.setEnabled(false);
    
                        btnVideoNext.setBackgroundResource(R.drawable.btn_video_next_selector);
                        btnVideoNext.setEnabled(true);
    
                    }
                    else if (position == mediaItems.size() - 1)
                    {
                        btnVideoNext.setBackgroundResource(R.drawable.btn_next_gray);
                        btnVideoNext.setEnabled(false);
    
                        btnVideoPre.setBackgroundResource(R.drawable.btn_video_pre_selector);
                        btnVideoPre.setEnabled(true);
    
                    }
                }
                else
                {
                    if (position == 0)
                    {
                        btnVideoPre.setBackgroundResource(R.drawable.btn_pre_gray);
                        btnVideoPre.setEnabled(false);
                    }
                    else if (position == mediaItems.size() - 1)
                    {
                        btnVideoNext.setBackgroundResource(R.drawable.btn_next_gray);
                        btnVideoNext.setEnabled(false);
                    }
                    else
                    {
                        setEnable(true);
                    }
                }
            }
            else if (uri != null)
            {
                //两个按钮设置灰色
                setEnable(false);
            }
        }
    
        private void setEnable(boolean isEnable)
        {
            if (isEnable)
            {
                btnVideoPre.setBackgroundResource(R.drawable.btn_video_pre_selector);
                btnVideoPre.setEnabled(true);
                btnVideoNext.setBackgroundResource(R.drawable.btn_video_next_selector);
                btnVideoNext.setEnabled(true);
            }
            else
            {
                //两个按钮设置灰色
                btnVideoPre.setBackgroundResource(R.drawable.btn_pre_gray);
                btnVideoPre.setEnabled(false);
                btnVideoNext.setBackgroundResource(R.drawable.btn_next_gray);
                btnVideoNext.setEnabled(false);
            }
    
        }
    

    20-判断uri是否网络资源&支持显示缓冲进度&手机播放电脑tomcat资源

    20.1 判断是否是网络的资源

        /**
         * 判断是否是网络的资源
         *
         * @param uri
         * @return
         */
        public boolean isNetUri(String uri)
        {
            boolean reault = false;
            if (uri != null)
            {
                if (uri.toLowerCase().startsWith("http") || uri.toLowerCase().startsWith("rtsp") || uri.toLowerCase().startsWith("mms"))
                {
                    reault = true;
                }
            }
            return reault;
        }
    

    20.2 在hanlder设置播放网络视频时候支持显示缓存进度

                        //缓存进度的更新
                        if (isNetUri)
                        {
                            //只有网络资源才有缓存效果
                            int buffer = videoview.getBufferPercentage();
                            int totalBuffer = buffer * seekbarVideo.getMax();
                            int secondaryProgress = totalBuffer / 100;
                            seekbarVideo.setSecondaryProgress(secondaryProgress);
                        }
    

    21-监听卡并且提示&监听拖动完成&显示网速

    21.1 监听卡并且提示

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="#33000000"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="3dp"
        android:visibility="gone">
    
        <ProgressBar
            android:layout_width="30dp"
            android:layout_height="30dp" />
    
        <TextView
            android:id="@+id/tv_buffer_netspeed"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="3dp"
            android:gravity="center"
            android:text="缓存中...30kb/s"
            android:textColor="#ffffff"
            android:textSize="10sp" />
    
    </LinearLayout>
    

    21.2监听拖动完成

     //播放完成了的监听
            videoview.setOnCompletionListener(new MyOnCompletionListener());
    
     class MyOnCompletionListener implements MediaPlayer.OnCompletionListener
        {
    
            @Override
            public void onCompletion(MediaPlayer mp)
            {
                playNextVideo();
    //            Toast.makeText(SystemVideoPlayer.this, "播放完成了="+uri, Toast.LENGTH_SHORT).show();
            }
        }
    
    
    private long lastTotalRxBytes = 0;
        private long lastTimeStamp = 0;
    
        /**
         * 得到网络速度
         * 每隔两秒调用一次
         *
         * @param context
         * @return
         */
        public String getNetSpeed(Context context)
        {
            String netSpeed = "0 kb/s";
            long nowTotalRxBytes = TrafficStats.getUidRxBytes(context.getApplicationInfo().uid) == TrafficStats.UNSUPPORTED ? 0 : (TrafficStats.getTotalRxBytes() / 1024);//转为KB;
            long nowTimeStamp = System.currentTimeMillis();
            long speed = ((nowTotalRxBytes - lastTotalRxBytes) * 1000 / (nowTimeStamp - lastTimeStamp));//毫秒转换
    
            lastTimeStamp = nowTimeStamp;
            lastTotalRxBytes = nowTotalRxBytes;
            netSpeed = String.valueOf(speed) + " kb/s";
            return netSpeed;
        }
    

    22-监听播放出错的处理

            //播放出错了的监听
            videoview.setOnErrorListener(new MyOnErrorListener());
    
    class MyOnErrorListener implements MediaPlayer.OnErrorListener
        {
    
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra)
            {
                // Toast.makeText(SystemVideoPlayer.this, "播放出错了哦", Toast.LENGTH_SHORT).show();
                startVitamioPlayer();
                return true;
            }
        }
    

    23-添加Vitamio插件变成万能播放器

    23.1,拷贝权限到项目中来

        <uses-permission android:name="android.permission.WAKE_LOCK" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    

    23.2 拷贝InitActivity的,在功能清单文件配置,代码如下:

        <!-- Don't forgot InitActivity -->
            <activity
                android:name="io.vov.vitamio.activity.InitActivity"
                android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
                android:launchMode="singleTop"
                android:theme="@android:style/Theme.NoTitleBar"
                android:windowSoftInputMode="stateAlwaysHidden" />
    

    23.3,新创建一个Activity名字叫VitamioVideoPlayerActivity

    重新创建布局文件activity_vitamio_videoplayer.xml,把布局文件里面的系统的VideoView换成Vitamio的VideoView,导入的包都要换成是Vitamio的

         <io.vov.vitamio.widget.VideoView
            android:id="@+id/surface_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    

    23.4.需要把VitamioVideoPlayerActivity在功能清单文件里面注册

          <activity android:name=".VitamioVideoPlayerActivity"
                android:configChanges="keyboardHidden|screenSize|orientation"
                android:screenOrientation="landscape"
                android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
                />
    

    23.5,要在加载布局文件之前,初始化解码器

    Vitamio.isInitialized(this);
    

    23.6,当系统播放器出错的时候,记得跳转到Vitmaio播放中,并且不要忘记携带数据

        /**
         * 启动Vitamio解码播放器
         * a,把数据按照原样传入VtaimoVideoPlayer播放器
         * b,关闭系统播放器
         */
        private void startVitamioPlayer()
        {
            if(videoview!=null)
            {
                videoview.stopPlayback();
            }
            Intent intent = new Intent(this, VitamioVideoPlayer.class);
            if(mediaItems!=null && mediaItems.size()>0)
            {
                Bundle bundle = new Bundle();
                bundle.putSerializable("videolist",mediaItems);
                intent.putExtras(bundle);
                intent.putExtra("position",position);
            }
            else if(uri!=null)
            {
                intent.setData(uri);
            }
            startActivity(intent);
            finish();//关闭页面
        }
    

    24-当万能播放器播放失败的提示

    24.1 当播放出错回调

            //播放出错了的监听
            videoview.setOnErrorListener(new MyOnErrorListener());
     class MyOnErrorListener implements MediaPlayer.OnErrorListener
        {
    
            @Override
            public boolean onError(MediaPlayer mp, int what, int extra)
            {
    //            Toast.makeText(SystemVideoPlayer.this, "播放出错了哦", Toast.LENGTH_SHORT).show();
                showErrorDialog();
                //1.播放的视频格式不支持--跳转到万能播放器继续播放
                //2.播放网络视频的时候,网络中断---1.如果网络确实断了,可以提示用于网络断了;2.网络断断续续的,重新播放
                //3.播放的时候本地文件中间有空白---下载做完成
                return true;
            }
        }
    
        private void showErrorDialog()
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("提示");
            builder.setMessage("抱歉,无法播放该视频!!");
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    finish();
                }
            });
            builder.show();
        }
    

    25-人为切换系统和万能播放器

    25.1 系统播放器和万能播放器手动切换

        /**
         * 切换播放器系统-->万能解码(Vitamio框架)
         */
        private void showSwichPlayerDialog()
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("系统播放器提醒您");
            builder.setMessage("当您播放视频,有声音没有画面的时候,请切换万能播放器播放");
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    startVitamioPlayer();
                }
            });
            builder.setNegativeButton("取消", null);
            builder.show();
        }
    
    
    
      /**
       * 设置标题和播放数据
       */
      private void setData()
        {
    
            if (mediaItems != null && mediaItems.size() > 0)
            {
                MediaItem mediaItem = mediaItems.get(position);
                tvName.setText(mediaItem.getName());//设置视频的名称
                isNetUri = utils.isNetUri(mediaItem.getData());
                videoview.setVideoPath(mediaItem.getData());
    
            }
            else if (uri != null)
            {
                tvName.setText(uri.toString());//设置视频的名称
                isNetUri = utils.isNetUri(uri.toString());
                videoview.setVideoURI(uri);
            }
            else
            {
                Toast.makeText(VitamioVideoPlayer.this, "帅哥你没有传递数据", Toast.LENGTH_SHORT).show();
            }
            setButtonState();
        }
    

    25.3-屏蔽系统播放器和Vitamio播放器切换的动画

    <style name="noAnimation_Theme" parent="android:Theme">
        <item name="android:windowAnimationStyle">@style/noAnimation</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>
    
    <style name="noAnimation">
        <item name="android:activityOpenEnterAnimation">@null</item>
        <item name="android:activityOpenExitAnimation">@null</item>
        <item name="android:activityCloseEnterAnimation">@null</item>
        <item name="android:activityCloseExitAnimation">@null</item>
        <item name="android:taskOpenEnterAnimation">@null</item>
        <item name="android:taskOpenExitAnimation">@null</item>
        <item name="android:taskCloseEnterAnimation">@null</item>
        <item name="android:taskCloseExitAnimation">@null</item>
        <item name="android:taskToFrontEnterAnimation">@null</item>
        <item name="android:taskToFrontExitAnimation">@null</item>
        <item name="android:taskToBackEnterAnimation">@null</item>
        <item name="android:taskToBackExitAnimation">@null</item>
    
    </style>
    

    使用样式:

    <activity android:name=".videoplayer.VitamioVideoPlayerActivity"
        android:screenOrientation="landscape"
        android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
        android:theme="@style/noAnimation_Theme"/>
    

    26-网络视频&xUtils3请求

    26.1 xUtils3联网请求

       /**
         * 从网络中加载视频数据
         */
        private void getDataFromNet()
        {
            //联网
            //视频内容
            RequestParams requestParams = new RequestParams(Constants.NET_URL);
            x.http().get(requestParams, new Callback.CommonCallback<String>()
            {
                @Override
                public void onSuccess(String result)
                {
                    LogUtil.e("联网成功==" + result);
                    //缓存数据
                    CacheUtils.putString(context, Constants.NET_URL, result);
                    //主线程
                    processData(result);
                }
    
                @Override
                public void onError(Throwable ex, boolean isOnCallback)
                {
                    LogUtil.e("联网失败==" + ex.getMessage());
                    showData();
                }
    
                @Override
                public void onCancelled(CancelledException cex)
                {
                    LogUtil.e("onCancelled==" + cex.getMessage());
                }
    
                @Override
                public void onFinished()
                {
                    LogUtil.e("onFinished==");
                }
            });
        }
    

    26.2 Json解析

        /**
         * 处理Json数据
         *
         * @param json
         */
        private void processData(String json)
        {
            if (!isLoadMore)
            {
                mediaItems = parseJson(json);
                showData();
            }
            else
            {
                //加载更多
                //要把得到更多的数据,添加到原来的集合中
    //            ArrayList<MediaItem> moreDatas = parseJson(json);
                isLoadMore = false;
                mediaItems.addAll(parseJson(json));
                adapter.notifyDataSetChanged();
                onLoad();
            }
        }
    
    /**
         * 解决json数据:
         * 1.用系统接口解析json数据
         * 2.使用第三方解决工具(Gson,fastjson)
         *
         * @param json
         * @return
         */
        private ArrayList<MediaItem> parseJson(String json)
        {
            ArrayList<MediaItem> mediaItems = new ArrayList<>();
            try
            {
                JSONObject jsonObject = new JSONObject(json);
                JSONArray jsonArray = jsonObject.optJSONArray("trailers");
    
                if (jsonArray != null && jsonArray.length() > 0)
                {
                    for (int i = 0; i < jsonArray.length(); i++)
                    {
                        JSONObject jsonObjectItem = (JSONObject) jsonArray.get(i);
                        if (jsonObjectItem != null)
                        {
                            MediaItem mediaItem = new MediaItem();
    
                            String movieName = jsonObjectItem.optString("movieName");
                            mediaItem.setName(movieName);
    
                            String videoTitle = jsonObjectItem.optString("videoTitle");//desc
                            mediaItem.setDesc(videoTitle);
    
                            String imageUrl = jsonObjectItem.optString("coverImg");//imageUrl
                            mediaItem.setImageUrl(imageUrl);
    
                            String hightUrl = jsonObjectItem.optString("hightUrl");//data
                            mediaItem.setData(hightUrl);
    
                            //把数据添加到集合
                            mediaItems.add(mediaItem);
                        }
                    }
                }
            }
            catch (JSONException e)
            {
                e.printStackTrace();
            }
            return mediaItems;
        }
    

    27-视频列表集成xListView支持下拉刷新&加载更多

        /**
         * 上拉刷新加载更多
         */
        private void getMoreDataFromNet()
        {
            //联网
            //视频内容
            RequestParams params = new RequestParams(Constants.NET_URL);
            x.http().get(params, new Callback.CommonCallback<String>()
            {
                @Override
                public void onSuccess(String result)
                {
                    LogUtil.e("联网成功==" + result);
                    isLoadMore = true;
                    //主线程
                    processData(result);
                }
    
                @Override
                public void onError(Throwable ex, boolean isOnCallback)
                {
                    LogUtil.e("联网失败==" + ex.getMessage());
                    isLoadMore = false;
                }
    
                @Override
                public void onCancelled(CancelledException cex)
                {
                    LogUtil.e("onCancelled==" + cex.getMessage());
                    isLoadMore = false;
                }
    
                @Override
                public void onFinished()
                {
                    LogUtil.e("onFinished==");
                    isLoadMore = false;
                }
            });
        }
    

    28-文本数据的缓存

    public class CacheUtils
    {
    
        /**
         * 保持数据
         *
         * @param context
         * @param key
         * @param values
         */
        public static void putString(Context context, String key, String values)
        {
            SharedPreferences sharedPreferences = context.getSharedPreferences("atguigu", Context.MODE_PRIVATE);
            sharedPreferences.edit().putString(key, values).commit();
        }
    
        /**
         * 得到缓存的数据
         *
         * @param context
         * @param key
         * @return
         */
        public static String getString(Context context, String key)
        {
            SharedPreferences sharedPreferences = context.getSharedPreferences("atguigu", Context.MODE_PRIVATE);
            return sharedPreferences.getString(key, "");
        }
    
        /**
         * 保持播放模式
         *
         * @param context
         * @param key
         * @param values
         */
        public static void putPlaymode(Context context, String key, int values)
        {
            SharedPreferences sharedPreferences = context.getSharedPreferences("hashub", Context.MODE_PRIVATE);
            sharedPreferences.edit().putInt(key, values).commit();
    
        }
    
        /*
        得到播放模式
         */
        public static int getPlaymode(Context context, String key)
        {
            SharedPreferences sharedPreferences = context.getSharedPreferences("hashub", Context.MODE_PRIVATE);
            return sharedPreferences.getInt(key, MusicPlayerService.REPEAT_NORMAL);
        }
    
    }
    

    相关文章

      网友评论

          本文标题:手机影音03

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