• Android Studio上手,基于VideoView的本地文件及流媒体播放器


    既然是第一个Android程序。少不了要Hello World。


    1. 新建安卓project



    2. 输入project名称



    3. 选择平台版本号



    4. 选择一个空的Activity



    5. 定制自己的Activity


    点击Finish后,便生成了可以直接执行的Hello World程序。

    以下開始讨论如何使这个仅仅能打印Hello World的程序可以播放本地和网络视频。

    此处附上功能文件夹结构:



    6. 布局文件

    首先须要又一次布局。

    设计器的设计结果是保存在“activity_video_view_demo.xml”这个XML文件里的。所以,略微花一点时间看下这个XML文件。就非常easy看懂。

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".VideoViewDemo">
    
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="= Stream Player ="
            android:id="@+id/textView"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:textIsSelectable="false"
            android:layout_alignParentBottom="false"
            android:gravity="center_horizontal" />
    
        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/url"
            android:layout_below="@+id/textView"
            android:layout_alignParentTop="false"
            android:layout_alignParentLeft="true"
            android:text="rtsp://ipaddr:port/domain"
            android:layout_alignRight="@+id/textView"
            android:layout_alignEnd="@+id/textView" />
    
        <RadioGroup
            android:id="@+id/radioGroup1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_below="@+id/url"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="false">
    
            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Stream"
                android:id="@+id/radioButtonStream"
                android:layout_below="@+id/url"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:checked="false"
                android:layout_alignBottom="@+id/start_play" />
    
            <RadioButton
                android:layout_width="wrap_content"
                android:layout_height="51dp"
                android:text="File"
                android:id="@+id/radioButtonFile"
                android:checked="false"
                android:layout_alignBottom="@+id/radioButtonStream"
                android:layout_toRightOf="@+id/radioButtonStream"
                android:layout_below="@+id/url" />
        </RadioGroup>
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="PLAY"
            android:id="@+id/start_play"
            android:layout_below="@+id/url"
            android:layout_alignRight="@+id/url"
            android:layout_alignEnd="@+id/url"
            android:layout_toRightOf="@+id/radioGroup1"
            android:layout_toEndOf="@+id/radioGroup1" />
    
        <VideoView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/rtsp_player"
            android:layout_below="@+id/start_play"
            android:layout_alignRight="@+id/url"
            android:layout_alignEnd="@+id/url" />
    
    </RelativeLayout>
    
    布局设计器效果:

    对比XML文件,最外层是一个关系布局。里面依次是TextView(用于显示标题);EditText(用于输入文件名称或流媒体的URL)。一个RadioGroup。当中包括两个RadioButton(用于区分是区网络流还是读本地文件);一个Button(单击開始播放)。一个VideoView(视频播放区)。

    当中的layout_width能够是wrap_content(依据内容自适应)。fill_parent(填充整个外部空间),match_parent(依据外部空间自适应),这个当视频播放区加载视频后会看出区别。android:id这个属性很重要。是Java程序中调用布局控件的关键。


    7. 源代码

    package com.example.chenth.videoviewdemo;
    
    import android.app.Activity;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.RadioButton;
    import android.widget.VideoView;
    
    public class VideoViewDemo extends Activity {
        /** Called when the activity is first created. */
    
        Button playButton ;
        VideoView videoView ;
        EditText rtspUrl ;
        RadioButton radioStream;
        RadioButton radioFile;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_video_view_demo);
    
            rtspUrl = (EditText)this.findViewById(R.id.url);
            playButton = (Button)this.findViewById(R.id.start_play);
            radioStream = (RadioButton)this.findViewById(R.id.radioButtonStream);
            radioFile = (RadioButton)this.findViewById(R.id.radioButtonFile);
    
            playButton.setOnClickListener(new Button.OnClickListener(){
                public void onClick(View v) {
                    if (radioStream.isChecked()) {
                        PlayRtspStream(rtspUrl.getEditableText().toString());
                    }
                    else if (radioFile.isChecked()){
                        PlayLocalFile(rtspUrl.getEditableText().toString());
                    }
                }
            });
    
            videoView = (VideoView)this.findViewById(R.id.rtsp_player);
    
        }
    
        //play rtsp stream
        private void PlayRtspStream(String rtspUrl){
            videoView.setVideoURI(Uri.parse(rtspUrl));
            videoView.requestFocus();
            videoView.start();
        }
    
        //play rtsp stream
        private void PlayLocalFile(String filePath){
            videoView.setVideoPath(Environment.getExternalStorageDirectory() + "/" + filePath);
            videoView.requestFocus();
            videoView.start();
        }
    }
    
    在on鞥的Create函数中依据ID从布局中获取控件,当playButton点击时依据RadioButton的选择(取网络流还是播放本地文件)调用不同的函数。(主要是用到了Android原生的VideoView。而这个控件播放网络流使用 videoView.setVideoURI()函数,播放本地文件使用setVideoPath()函数)。

    8. 添加权限

    在调试这个程序的时候,总是出现“Can't Play This Video”或者“无法播放该视频”的错误。我也为此花费了非常多时间。最后发现是由于没有给这个APP赋予訪问网络和本地文件的权限。

    权限配置在AndroidManifest.xml这个文件里。

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.chenth.videoviewdemo" >
    
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".VideoViewDemo"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>
    
    注意"uses-permission"的两行。分别表示该应用须要訪问网络,以及读写本地文件,这两个权限相应了播放网络流和本地文件。
    加了这两行以后。打包安装时,就能够看到APP想Android系统申请权限的提示了。


    9. 在模拟器上调试

    点击Run app,会出现选择设备的窗体,没有现成设备的话就新增一个。





    由于我不知道模拟器相应的根文件夹在PC的什么位置,所以无法在模拟器中直接測试播放本地文件。

    另外。在模拟器中測试播放网络流也不成功,推測应该是模拟器权限未设置好。所以,直接进入最后一步吧。


    10. 打包公布

    点击菜单条的Build -> Generate Signed APK。第一次使用时会要求创建一个Key,就创建吧。然后一路Next 就能够了。最后把生成的apk文件复制到手机,安装。搞定。

    最后上手机截屏效果:一张是播放RTSP实时流,还有一张是我家小盆友的录像。




    11. 附:Android原生VideoView的播放缓冲大小好像是不能调整的。导致网络RTSP流的延时达到了9-10秒。各位看官假设知道什么好的办法。欢迎留言告知,谢谢!


  • 相关阅读:
    springcloud中常用的注解
    MySQL--Profiling和Trace使用
    MySQL Execution Plan--IN查询计划
    MySQL Config--参数system_time_zone和参数time_zone
    MySQL Replication--全局参数gtid_executed和gtid_purged
    MySQL Transaction--事务无法正常回滚导致的异常
    MySQL Execution Plan--数据排序操作
    MySQL Session--批量KILL会话
    MySQL Transaction--MySQL与SQL Server在可重复读事务隔离级别上的差异
    MySQL Transaction--事务相关查询
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5074364.html
Copyright © 2020-2023  润新知