既然是第一個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秒。各位看官假設知道什么好的辦法。歡迎留言告知,謝謝!
