搜索
您的当前位置:首页正文

手机影音03

来源:二三娱乐

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 
    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 
    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 
        x.http().get(requestParams, new 
        {
            @Override
            public void onSuccess(String result)
            {
                LogUtil.e("联网成功==" + result);
                //缓存数据
                CacheUtils.putString(context,  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 
        x.http().get(params, new 
        {
            @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, 
    }

    /**
     * 得到缓存的数据
     *
     * @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, 

    }

    /*
    得到播放模式
     */
    public static int getPlaymode(Context context, String key)
    {
        SharedPreferences sharedPreferences = context.getSharedPreferences("hashub", Context.MODE_PRIVATE);
        return sharedPreferences.getInt(key, MusicPlayerService.REPEAT_NORMAL);
    }

}

Top