本文簡介 媒體包提供了可管理各種媒體類型的類。這些類可提供用於執行音頻和視頻操作。除了基本操作之外,還可提供鈴聲管理、臉部識別以及音頻路由控制。本文說明了音頻和視頻操作。 範圍: 本文旨在針對希望簡單瞭解Android編程的初學者而設計。本文將指導你逐步開發使用媒體(音頻和視頻)的應用程序。本文假定你已安裝了可開發應用程序的Android和必要的工具,同時還假定你已熟悉Java或掌握面向對象的編程概念。如欲查詢更多有關Android的詳情,請參閱三星移動創新者園地(SMI)知識庫網站。http://innovator.samsungmobile.com/cn/platform.main.do?platformId=1 簡介 通過“android.media”包支持音頻和視頻操作。除了基本操作之外,還可以提供用於鈴聲管理、臉部識別以及音頻路由控制的各種類。 Android通過MediaPlayer類支持播放音頻和視頻。MediaPlayer類處於Android media包的核心位置。除了MediaPlayer類之外,SoundPool和JetPlayer類也可提供用來播放音頻文件。 播放音頻文件 MediaPlayer 是播放媒體文件最爲廣泛使用的類。MediaPlayer已設計用來播放大容量的音頻文件以及同樣可支持播放操作(停止、開始、暫停等)和查找操作的流媒體。其還可支持與媒體操作相關的監聽器。通過以下方式可完成播放MediaPlayer中的音頻和視頻: · 從源文件播放。 · 從文件系統播放。 · 從流媒體播放。
MediaPlayer監聽器 定義了部分監聽器,如OnCompletionListener、OnPrepareListener、OnErrorListener、OnBufferingUpdateListener、OnInfoListener,OnVideoSizeChangedListener和OnSeekCompleteListener。當在播放過程中到達媒體源末端時,可調用OnCompletionListener onCompletion(MediaPlayer mp)事件。你也可使用監聽器事件來從列表中播放下一首歌曲或釋放媒體播放器對象。當準備播放媒體源時,將可調用OnPrepareListener onPrepared(MediaPlayer mp)事件。你可以開始播放onPrepared()方法中的歌曲。當在異步操作過程中出現錯誤時(其他錯誤將在調用方法時拋出異常),將可調用OnErrorListener boolean onError(MediaPlayer mp, int what, int extra)事件。參數what指明瞭已發生錯誤的類型。這可能爲MEDIA_ERROR_UNKNOWN or MEDIA_ERROR_SERVER_DIED。參數extra指明瞭與錯誤相關的附加信息。 從res播放音頻 這是播放音頻文件最普通的方法。在此情況下,音頻文件應存在於該項目的raw或assets文件夾中,如圖1中所示。
如欲訪問一個原資源,僅需使用無擴展名的小寫文件名稱: context appContext = getApplicationContext(); MediaPlayer mMediaPlayer = MediaPlayer.create(appContext,R.raw.samplemp3); mMediaPlayer.start(); 或 MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.samplemp3); mMediaPlayer.start(); 如欲停止播放,調用stop()。如果你希望重播該媒體,則須在再次調用start()之前reset()(重置())並prepare()(準備())該MediaPlayer對象。(create()首次調用prepare()。)如欲暫停播放,調用pause()。使用start()可從你已暫停的地方恢復播放。 從文件系統播放音頻 訪問音頻文件的第二種方法是從文件系統,即SD卡。大多數音頻資源均存在於SD卡中。在研究如何通過SD卡訪問音頻文件之前,讓我們看一下如何在SD卡中加載文件。通過窗口> 顯示視圖> 其他,可打開Eclipse IDE中的FileExplorer視圖。其將打開顯示視圖。如圖2中所示,選擇Android >FileExplorer。
一旦選擇File Explorer(文件管理器),即將會打開File Explorer視圖,如圖3所示。
現在,可將文件推入SD卡中,在File Explorer中選擇sdcard文件夾,並使用位於右上角的右箭頭來選擇按鈕。此操作可開啓對話框,可使你選擇文件。選擇你所需上傳至SD卡中的文件。將文件推入SD卡中後,如圖4中顯示了可用的內容。
通過以下方式來從SD卡訪問文件 String pathToFile = "/sdcard/samplemp3.mp3"; //create mediaplayer mediaPlayer = new MediaPlayer(); //set audio file path try { mediaPlayer.setDataSource(pathToFile); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //Prepare mediaplayer try { mediaPlayer.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //start mediaPlayer mediaPlayer.start(); 首先,創建一個新的MediaPlayer實例。其次,將待播放的音頻文件(文件路徑)設置爲MediaPlayer實例的數據源。在播放器開始播放歌曲之前,必須準備好MediaPlayer對象。prepare()方法爲阻塞方法,並可阻塞直至媒體播放器準備播放歌曲。非阻塞方法prepareAsync()也可進行提供。如果媒體播放器用來從流媒體中播放歌曲,並且在播放歌曲之前需要緩衝數據,則應使用非阻塞prepare方法。現在使用以下內容來播放控制方法,如Start()、stop()等。在可設置用於部分其他歌曲文件之前,媒體播放器對象須進行重置。媒體播放器在其使用後須予以釋放。此操作使用release()方法來完成。Release()方法可釋放與MediaPlayer對象相關聯的資源。當你使用MediaPlayer來完成操作時,這被認爲是調用此方法的最佳實踐。我們也可通過以下方式來創建媒體播放器 String pathToFile = "/sdcard/samplemp3.mp3"; MediaPlayer filePlayer = MediaPlayer.create( appContext, Uri.parse(pathToFile) ); 此處可通過解析給定的已編譯URI字符串來使用URI類創建Uri。 從網頁播放音頻 使用與用於訪問SD卡中存有的音頻文件的相同代碼,可完成訪問網站中的音頻文件。唯一的變化就是文件路徑。此處的路徑將爲網站URL,其指向音頻資源文件。此處最重要的部分就是使用互聯網提取數據,因此必須獲取訪問互聯網的許可。在AndroidManifest.xml文件中設置互聯網許可 <uses-permission android:name="android.permission.INTERNET"> </uses-permission> 除了URL路徑外,該代碼保持相同 String urlPath = "http:/www.xyz.com/…/samplemp3.mp3"; //create new mediaplayer mediaPlayer = new MediaPlayer(); //set audio file path try { mediaPlayer.setDataSource(urlPath); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //Prepare mediaplayer try { mediaPlayer.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //Start mediaplayer mediaPlayer.start(); 或者,我們也可通過以下方式創建媒體播放器 String urlPath = "http:/www.xyz.com/…/samplemp3.mp3"; MediaPlayer filePlayer = MediaPlayer.create( appContext, Uri.parse(urlPath) ); 此處可通過解析給定的已編譯URI字符串來使用URI類創建Uri。類與MediaPlayer類相對。該類設計用於快速播放一套預先定義的相對較短的聲音示例。它是示例的集合,這些示例可從APK內部的資源或從文件系統的文件載入內存中。最典型的用例是在要求低延時的遊戲中的音效池。除了預先加載和播放聲音等基本操作外,SoundPool類還支持以下功能: SoundPool SoundPool · 設置可同時播放的最高的聲音數 · 優先處理聲音,以便達到最大極限時將會減弱優先級別低的聲音 · 在完成播放之前暫停和停止聲音 · 循環聲音 · 更改播放速率(實際上是指每個聲音音調) · 設置立體聲音量(左聲道和右聲道不同)
如圖1所示,通過SoundPool類使用.ogg文件來播放音頻文件。以下代碼片段說明了SoundPool類的用法。 private int BIG_WAVE = 1; /* Initialize SoundPool 1 – number of sounds that will be loaded. AudioManager.STREAM_MUSIC- Stream type 0 – Quality of the sound. Currently no effect */
SoundPool soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
//Create HashMap HashMap soundPoolMap = new HashMap();
//Create AudioManager AudioManager mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE);
OR
AudioManager mAudioManager = (AudioManager)getContext().getSystemService(AUDIO_SERVICE);
//Load audio file int soundID = mSoundPool.load(this, R.raw.bigwave, 1);
//Put key value pair in HashMap soundPoolMap.put(BIG_WAVE, soundID);
//Play sound int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); int actualVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundPool.play( mSoundPoolMap.get(BIG_WAVE), streamVolume, streamVolume, 1, 0, 1f);
從res播放音頻 使用SoundPool類load (Context context, int resId, int priority)方法可從原文件夾加載音頻文件。如果你希望從原資源文件“bigwave.mp3”加載聲音,則應將“R.raw.bigwave”指定爲資源ID。返回可被使用的整數值SoundID來播放聲音。 從文件系統播放音頻 使用SoundPool類load (String path, int priority)方法可從原文件夾加載音頻文件。如果你希望從原資源文件“bigwave.mp3”加載聲音,則應將“R.raw.bigwave”指定爲資源ID。此操作能返回可被使用的整數值SoundID來播放聲音。 ToneGenerator 該類提供了可播放雙音多頻(DTMF)音、呼叫監控音和專有音的各種方法。對象要求一個輸出流類型和音量。startTone()可用來播放聲音。startTone()方法可在指定的時間段開始播放指定類型的聲音。 ToneGenerator //Output Stream Type and Volume ToneGenerator tg=new ToneGenerator(AudioManager.STREAM_RING, 100); //Play Tone tg.startTone(ToneGenerator.TONE_CDMA_ABBR_ALERT);
播放視頻文件
VideoView Android提供了專業化的視圖控制android.widget.VideoView,其可壓縮創建並初始化MediaPlayer。VideoView類可從各種源(如資源或內容提供商)加載圖片,並且可負責從該視頻計算其尺寸,以便其可在任何佈局管理器中使用。同樣,該類還可提供各種顯示選項,如縮放比例和着色。可用來顯示SDCard FileSystem中存在的視頻文件或聯機存在的文件。如欲添加VideoView控件,res文件夾中存在的佈局文件將可能出現如下情況 VideoView <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" <VideoView android:id="@+id/videoView" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout>
並且顯示如下代碼片段 //Create VideoView VideoView videoView = (VideoView)this.findViewById(R.id.videoView); //Create MediaController MediaController mc = new MediaController(this); //Set MediaController to VideoView videoView.setMediaController(mc); //Set video path of SD Card videoView.setVideoURI(Uri.parse("file:///sdcard/samplemp4.mp4")); OR //Set video web path videoView.setVideoURI(Uri.parse("http://www.xyz.com/../sample3gp.3gp")); //Set requestFocus videoView.requestFocus(); //Play Video videoView.start(); 從文件系統播放視頻從將訪問視頻文件的地方設置視頻路徑。此處指定了文件系統的路徑。使用Uri.parse(String path)靜態方法,其可將該字符串轉換爲Uri。從網頁播放視頻此操作與從文件系統播放視頻的方法相同,唯一的區別就是路徑。此處的路徑指向網站。 VideoView setVideoURI(Uri uri) SurfaceView 可允許我們指定我們自己的顯示面,並可允許直接操控媒體播放器基礎實例。如欲使用媒體播放器來查看視頻內容,首先要準備一個將可顯示該視頻的顯示面。媒體播放器要求一個SurfaceHolder對象來顯示視頻內容,該對象可使用setDisplay()方法來予以分配。如欲在UI佈局中包括Surface Holder,使用存在於res文件夾中的佈局文件中的SurfaceView控件。 SurfaceView <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <SurfaceView android:id="@+id/surface" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> </SurfaceView> </LinearLayout> 以下代碼片段說明了如何創建SurfaceView和SurfaceHolder。
//create SurfaceView SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surface); //get SurfaceHolder SurfaceHolder holder = mPreview.getHolder(); //add callback holder.addCallback(this); //set Surface Type holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //set Surface size Holder.setFixedSize(width, height); //specify the width and height here 如欲顯示視頻,需要執行SurfaceHolder.Callback接口。SurfaceHolder.Callback接口有三種方法 @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { } @Override public void surfaceCreated(SurfaceHolder holder) { } @Override public void surfaceDestroyed(SurfaceHolder arg0) { } 類有助於我們控制表面(如果表面發生變化,包括大小或表面的格式…)。一旦已創建表面,即可調用surfaceCreated(SurfaceHolder holder)。然後,創建一個MediaPlayer對象並設定其他參數。 SurfaceHolder 從res播放視頻 此處需要使用MediaPlayer 靜態方法MediaPlayer create (Context context, int resid)來創建MediaPlayer對象。該媒體播放器要求一個SurfaceHolder對象來顯示視頻內容,該對象可使用setDisplay()方法來予以分配。 //Create MediaPlayer from res MediaPlayer mMediaPlayer = MediaPlayer.create(this, R.raw.samplemp4); //Set the display mMediaPlayer.setDisplay(holder); //Set other parameters mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); //start the player mMediaPlayer.start();
從文件系統播放視頻 在此情況下,需要使用setDataSource (String path)方法來將文件路徑設置爲MediaPlayer。然後,需要使用prepare()方法來準備mediaplayer。prepare()方法可同步準備播放器進行播放。設置datasource和顯示面後,你需要調用prepare()或prepareAsync()。使用try–catch Exception語句,因爲特定的方法(如setDataSource()、prepare())可能會拋出異常。 String pathToFile = "/sdcard/samplemp4.mp4"; // Create a new media player and set the listeners MediaPlayer mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDataSource(pathToFile); mMediaPlayer.setDisplay(holder); mMediaPlayer.prepare(); // set listeners, if required by application mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.start();
從網頁播放視頻 在此情況下,文件路徑需要予以變更,並設置至可訪問視頻的網站。其他的仍保持相同。 String pathToFile = "http://www.xyz.com/.../samplemp4.mp4"; // Create a new media player and set the listeners MediaPlayer mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDataSource(pathToFile); mMediaPlayer.setDisplay(holder); mMediaPlayer.prepare(); // set listeners, if required by application mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.start();
示例 以下示例說明了可播放res文件夾、系統文件和互聯網中存在的音頻和視頻文件的ediaPlayer、SoundPool、 ToneGenerator、VideoView、SurfaceView類和MediaPlayer監聽器的用法。一旦開啓,該應用程序即可顯示兩個選項,即音頻或視頻。Xml和代碼如下所列出 main.xml <<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <<Button android:text="Audio" android:id="@+id/button1" android:layout_height="wrap_content" android:layout_width="match_parent"> <</Button> <<Button android:text="Video" android:id="@+id/button2" android:layout_height="wrap_content" android:layout_width="match_parent"> <</Button> </LinearLayout>
AudioVideoPlayer package com.samsung.player; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class AudioVideoPlayer extends Activity implements OnClickListener{ private Button btnAudio; private Button btnVideo; public static final int AUDIO = 1; public static final int VIDEO = 2; public static final String PLAY_WHAT = "AUDIO_VIDEO"; public static final String PLAY_AUDIO = "AUDIO"; public static final String PLAY_VIDEO = "VIDEO"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnAudio = (Button)findViewById(R.id.button1); btnAudio.setOnClickListener(this); btnVideo = (Button)findViewById(R.id.button2); btnVideo.setOnClickListener(this); } public void onClick(View v) {} if(v == btnAudio) { Intent intent = new Intent(this.getApplication(),MyPlayerMenu.class); intent.putExtra(PLAY_WHAT, AUDIO); startActivity(intent); } else if(v == btnVideo) { Intent intent = new Intent(this.getApplication(),MyPlayerMenu.class); intent.putExtra(PLAY_WHAT, VIDEO); startActivity(intent); } } 一旦選擇音頻,該應用程序即可顯示以下所列出的音頻菜單 myplayermenu.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
<Button android:text="Play Audio from res" android:id="@+id/menubutton1" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button>
<Button android:text="Play Audio from filesystem" android:id="@+id/menubutton2" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button>
<Button android:text="Play Audio from web stream" android:id="@+id/menubutton3" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> <Button android:text="Play Audio Tone (ToneGenerator)" android:id="@+id/menubutton4" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> <Button android:text="SoundPool" android:id="@+id/menubutton5" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> </LinearLayout>
MyPlayerMenu package com.samsung.player; import android.app.Activity; import android.content.Intent; import android.media.AudioManager; import android.media.ToneGenerator; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MyPlayerMenu extends Activity implements OnClickListener { private Button btnRes; private Button btnFile; private Button btnWeb; private Button btnTone; private Button btnSoundPool; private int value; public static final int PLAY_AUDIO_FROM_RES = 3; public static final int PLAY_AUDIO_FROM_FILESYSTEM = 4; public static final int PLAY_AUDIO_FROM_WEB = 5; public static final int PLAY_AUDIO_FROM_TONE = 6; public static final int PLAY_AUDIO_FROM_SOUNDPOOL = 7; public static final int PLAY_VIDEO_FROM_RES = 8; public static final int PLAY_VIDEO_FROM_FILESYSTEM = 9; public static final int PLAY_VIDEO_FROM_WEB = 10; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myplayermenu); btnRes = (Button)findViewById(R.id.menubutton1); btnRes.setOnClickListener(this); btnFile = (Button)findViewById(R.id.menubutton2); btnFile.setOnClickListener(this); btnWeb = (Button)findViewById(R.id.menubutton3); btnWeb.setOnClickListener(this); btnTone = (Button)findViewById(R.id.menubutton4); btnTone.setOnClickListener(this); btnSoundPool = (Button)findViewById(R.id.menubutton5); btnSoundPool.setOnClickListener(this); Bundle extras = getIntent().getExtras(); value = extras.getInt(AudioVideoPlayer.PLAY_WHAT); if(value == AudioVideoPlayer.VIDEO) { btnRes.setText("Play Video from res"); btnFile.setText("Play Video from file"); btnWeb.setText("Play Video from web"); btnTone.setEnabled(false); btnSoundPool.setEnabled(false); }else if(value == AudioVideoPlayer.AUDIO) { btnRes.setText("Play Audio from res"); btnFile.setText("Play Audio from file"); btnWeb.setText("Play Audio from web"); btnTone.setEnabled(true); btnSoundPool.setEnabled(true); } } public void onClick(View v) { if(v == btnRes) { Intent intent = null; if(value == AudioVideoPlayer.AUDIO) { intent = new Intent(this.getApplication(),MyAudioPlayer.class); intent.putExtra(AudioVideoPlayer.PLAY_AUDIO, PLAY_AUDIO_FROM_RES); }else { intent = new Intent(this.getApplication(),MySurfaceViewVideoPlayer.class); intent.putExtra(AudioVideoPlayer.PLAY_VIDEO, PLAY_VIDEO_FROM_RES); } startActivity(intent); }else if(v == btnFile) { Intent intent = null; if(value == AudioVideoPlayer.AUDIO) { intent = new Intent(this.getApplication(),MyAudioPlayer.class); intent.putExtra(AudioVideoPlayer.PLAY_AUDIO, PLAY_AUDIO_FROM_FILESYSTEM); } else { intent = new Intent(this.getApplication(),MyVideoPlayerMenu.class); intent.putExtra(AudioVideoPlayer.PLAY_VIDEO, PLAY_VIDEO_FROM_FILESYSTEM); } startActivity(intent); }else if(v == btnWeb) { Intent intent = new Intent(this.getApplication(),MyAudioPlayer.class); if(value == AudioVideoPlayer.AUDIO) { intent.putExtra(AudioVideoPlayer.PLAY_AUDIO, PLAY_AUDIO_FROM_WEB); }else { intent = new Intent(this.getApplication(),MyVideoPlayerMenu.class); intent.putExtra(AudioVideoPlayer.PLAY_VIDEO, PLAY_VIDEO_FROM_WEB); } startActivity(intent); }else if(v == btnTone) { ToneGenerator tg=new ToneGenerator(AudioManager.STREAM_RING, 100); tg.startTone(ToneGenerator.TONE_CDMA_ABBR_ALERT); }else if(v == btnSoundPool) { Intent intent = new Intent(this.getApplication(),MySoundPoolAudioPlayer.class); intent.putExtra(AudioVideoPlayer.PLAY_AUDIO, PLAY_AUDIO_FROM_SOUNDPOOL); startActivity(intent); } } } 一旦從res、文件系統和網頁選擇音頻,則MyAudioPlayer可獲調用。 myaudioplayer.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:id="@+id/myaudioplayer" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:text="Text" android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:text="Play" android:id="@+id/playButton" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> </LinearLayout>
MyAudioPlayer package com.samsung.player; import java.io.IOException; import android.app.Activity; import android.media.MediaPlayer; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MyAudioPlayer extends Activity implements OnClickListener{ private Button btnPausePlay; private MediaPlayer mediaPlayer; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myaudioplayer); btnPausePlay = (Button)findViewById(R.id.playButton); btnPausePlay.setOnClickListener(this); btnPausePlay.setText("Pause"); Bundle extras = getIntent().getExtras(); int value = extras.getInt(AudioVideoPlayer.PLAY_AUDIO); playAudio(value); } private void playAudio(int value) { if(value == MyPlayerMenu.PLAY_AUDIO_FROM_RES) { mediaPlayer = MediaPlayer.create(this, R.raw.samplemp3); mediaPlayer.start(); } else if(value == MyPlayerMenu.PLAY_AUDIO_FROM_FILESYSTEM) { String pathToFile = "/sdcard/samplemp3.mp3"; //Uri uri = Uri.parse(pathToFile); //mediaPlayer = MediaPlayer.create(this, uri); mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource(pathToFile); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { mediaPlayer.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } mediaPlayer.start(); } else if(value == MyPlayerMenu.PLAY_AUDIO_FROM_WEB) { String pathToFile = "http://www.xyz.com/Audio/sample.mp3"; //Uri uri = Uri.parse(pathToFile); //mediaPlayer = MediaPlayer.create(this, uri); mediaPlayer = new MediaPlayer(); try { mediaPlayer.setDataSource(pathToFile); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { mediaPlayer.prepare(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } mediaPlayer.start(); } } // Initiate media player pause private void demoPause(){ mediaPlayer.pause(); btnPausePlay.setText("Play"); } // Initiate playing the media player private void demoPlay(){ mediaPlayer.start(); btnPausePlay.setText("Pause"); } public void onClick(View v) { if(v == btnPausePlay) { if(mediaPlayer.isPlaying()) { demoPause(); } else { demoPlay(); } } } @Override protected void onDestroy() { super.onDestroy(); releaseMediaPlayer(); } private void releaseMediaPlayer() { if (mediaPlayer != null) { mediaPlayer.release(); mediaPlayer = null; } } }
一旦選擇SoundPool,該應用程序即可顯示如下顯示的SoundPool菜單 mysoundpoolplayermenu.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="BigWave" android:id="@+id/soundbutton1" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> <Button android:text="FlameMagic" android:id="@+id/soundbutton2" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> <Button android:text="MetalHit" android:id="@+id/soundbutton3" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> <Button android:text="TornadoMagic" android:id="@+id/soundbutton4" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> </LinearLayout>
MySoundPoolAudioPlayer package com.samsung.player; import java.util.HashMap; import android.app.Activity; import android.media.AudioManager; import android.media.SoundPool; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MySoundPoolAudioPlayer extends Activity implements OnClickListener{ private Button btnBigWave; private Button btnFlameMagic; private Button btnMetalHit; private Button btnTornadoMagic; private SoundPool mSoundPool; private HashMap mSoundPoolMap; private AudioManager mAudioManager; public static final int BIG_WAVE = 11; public static final int FLAME_MAGIC = 12; public static final int METAL_HIT = 13; public static final int TORNADO = 14; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.mysoundpoolplayermenu); btnBigWave = (Button)findViewById(R.id.soundbutton1); btnBigWave.setOnClickListener(this); btnFlameMagic = (Button)findViewById(R.id.soundbutton2); btnFlameMagic.setOnClickListener(this); btnMetalHit = (Button)findViewById(R.id.soundbutton3); btnMetalHit.setOnClickListener(this); btnTornadoMagic = (Button)findViewById(R.id.soundbutton4); btnTornadoMagic.setOnClickListener(this); loadSoundPool(); } private void loadSoundPool() { mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0); mSoundPoolMap = new HashMap(); mAudioManager = (AudioManager)getSystemService(AUDIO_SERVICE); int soundID = mSoundPool.load(this, R.raw.bigwave, 1); //OR //String pathToFile = "/sdcard/bigwave.ogg"; //int soundID = mSoundPool.load(pathToFile, 1); addSound(BIG_WAVE, soundID); soundID = mSoundPool.load(this, R.raw.flamemagic, 1); addSound(FLAME_MAGIC, soundID); soundID = mSoundPool.load(this, R.raw.metalhit, 1); addSound(METAL_HIT, soundID); soundID = mSoundPool.load(this, R.raw.tornadomagic, 1); addSound(TORNADO, soundID); } private void addSound(int index, int SoundID) { mSoundPoolMap.put(index, SoundID); } public void playAudio(int index) { int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); /*float actualVolume = (float) mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); float maxVolume = (float) mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); float streamVolume = actualVolume / maxVolume; */ mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f); } public void playLoopAudio(int index) { int streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, -1, 1f); } @Override protected void onDestroy() { super.onDestroy(); } public void onClick(View v) { if(v == btnBigWave) { playAudio(BIG_WAVE); }else if(v == btnFlameMagic) { playAudio(FLAME_MAGIC); }else if(v == btnMetalHit) { playAudio(METAL_HIT); }else if(v == btnTornadoMagic) { playAudio(TORNADO); } } }
同樣,一旦從AudioVideoPlayer類中顯示的主菜單選擇視頻選項,則其可顯示子菜單爲該xml和類中所顯示的VideoView和SurfaceView。 myvideoplayermenu.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="Play using VideoView" android:id="@+id/menubutton1" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> <Button android:text="Play using SurfaceView" android:id="@+id/menubutton2" android:layout_height="wrap_content" android:layout_width="match_parent"> </Button> </LinearLayout>
MyVideoPlayerMenu
package com.samsung.player; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MyVideoPlayerMenu extends Activity implements OnClickListener{ private Button btnVideoView; private Button btnSurfaceView; private int value; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.myvideoplayermenu); btnVideoView = (Button)findViewById(R.id.menubutton1); btnVideoView.setOnClickListener(this); btnSurfaceView = (Button)findViewById(R.id.menubutton2); btnSurfaceView.setOnClickListener(this); Bundle extras = getIntent().getExtras(); value = extras.getInt(AudioVideoPlayer.PLAY_VIDEO); } public void onClick(View v) { if(v == btnVideoView) { Intent intent = new Intent(this.getApplication(),MyVideoViewVideoPlayer.class); intent.putExtra(AudioVideoPlayer.PLAY_VIDEO, value); startActivity(intent); }else if(v == btnSurfaceView) { Intent intent = new Intent(this.getApplication(),MySurfaceViewVideoPlayer.class); intent.putExtra(AudioVideoPlayer.PLAY_VIDEO, value); startActivity(intent); } } } 如選擇了VideoView則VideoView將顯示在xml以及類文件的列表中 myvideoviewvideoplayer
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <VideoView android:id="@+id/videoView" android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout>
MyVideoViewVideoPlayer
package com.samsung.player;
import android.app.Activity; import android.net.Uri; import android.os.Bundle; import android.widget.MediaController; import android.widget.VideoView;
public class MyVideoViewVideoPlayer extends Activity {
private VideoView videoView; /** Called when the activity is first created. */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.myvideoviewvideoplayer);
videoView = (VideoView)this.findViewById(R.id.videoView); MediaController mc = new MediaController(this); videoView.setMediaController(mc);
Bundle extras = getIntent().getExtras(); int value = extras.getInt("VIDEO"); playVideo(value); }
private void playVideo(int value) { if(value == MyPlayerMenu.PLAY_VIDEO_FROM_FILESYSTEM) {file:///sdcard/samplemp4.mp4")); videoView.setVideoURI(Uri.parse(" videoView.requestFocus(); videoView.start(); } else if(value == MyPlayerMenu.PLAY_VIDEO_FROM_WEB) { http://www.xyzo.com/.../sample3gp.3gp")); videoView.setVideoURI(Uri.parse(" videoView.requestFocus(); videoView.start(); } } }
mysurfaceviewvideoplayer.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <SurfaceView android:id="@+id/surface" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> </SurfaceView> </LinearLayout>
MySurfaceViewVideoPlayer
package com.samsung.player;
import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnPreparedListener; import android.media.MediaPlayer.OnVideoSizeChangedListener; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView;
public class MySurfaceViewVideoPlayer extends Activity implements OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
private int mVideoWidth; private int mVideoHeight; private boolean mIsVideoSizeKnown = false; private boolean mIsVideoReadyToBePlayed = false;
private MediaPlayer mMediaPlayer; private SurfaceView mPreview; private SurfaceHolder holder;
/** * Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.mysurfaceviewvideoplayer); mPreview = (SurfaceView) findViewById(R.id.surface); holder = mPreview.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); }
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { if (width == 0 || height == 0) { return; } mIsVideoSizeKnown = true; mVideoWidth = width; mVideoHeight = height; if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) { startVideoPlayback(); } }
public void onPrepared(MediaPlayer mediaplayer) { mIsVideoReadyToBePlayed = true; if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) { startVideoPlayback(); } }
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) { }
public void surfaceDestroyed(SurfaceHolder surfaceholder) { }
public void surfaceCreated(SurfaceHolder holder) { Bundle extras = getIntent().getExtras(); int value = extras.getInt(AudioVideoPlayer.PLAY_VIDEO); playVideo(value); } private void playVideo(Integer value) { doCleanUp(); try { switch (value) { case MyPlayerMenu.PLAY_VIDEO_FROM_RES: mMediaPlayer = MediaPlayer.create(this, R.raw.samplemp4); mMediaPlayer.setDisplay(holder); mMediaPlayer.setOnVideoSizeChangedListener(this); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mMediaPlayer.start(); break; case MyPlayerMenu.PLAY_VIDEO_FROM_FILESYSTEM: String pathToFile = "/sdcard/samplemp4.mp4"; // Create a new media player and set the listeners mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDataSource(pathToFile); mMediaPlayer.setDisplay(holder); mMediaPlayer.prepare(); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnVideoSizeChangedListener(this); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); break; case MyPlayerMenu.PLAY_VIDEO_FROM_WEB: http://www.xyz.com/.../sample3gp.3gp"; String pathToWeb= " mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDataSource(pathToWeb); mMediaPlayer.setDisplay(holder); mMediaPlayer.prepare(); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnVideoSizeChangedListener(this); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); break; } } catch (Exception e) { } } @Override protected void onPause() { super.onPause(); releaseMediaPlayer(); doCleanUp(); }
@Override protected void onDestroy() { super.onDestroy(); releaseMediaPlayer(); doCleanUp(); }
private void releaseMediaPlayer() { if (mMediaPlayer != null) { mMediaPlayer.release(); mMediaPlayer = null; } }
private void doCleanUp() { mVideoWidth = 0; mVideoHeight = 0; mIsVideoReadyToBePlayed = false; mIsVideoSizeKnown = false; }
private void startVideoPlayback() { holder.setFixedSize(mVideoWidth, mVideoHeight); mMediaPlayer.start(); } }
以下是AndroidManifest.xml文件 AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.samsung.player" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AudioVideoPlayer" android:label="@string/app_name"> <intent-filter>
</intent-filter> </activity> <activity android:name=".MyPlayerMenu" android:label="PlayerMenu"> <intent-filter> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity>
<activity android:name=".MyAudioPlayer" android:label="AudioPlayer"> <intent-filter> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity>
<activity android:name=".MySoundPoolAudioPlayer" android:label="SoundPool AudioPlayer"> <intent-filter> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity>
<activity android:name=".MyVideoPlayerMenu" android:label="VideoPlayerMenu"> <intent-filter> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity>
<activity android:name=".MySurfaceViewVideoPlayer" android:label="SurfaceView VideoPlayer"> <intent-filter> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity>
<activity android:name=".MyVideoViewVideoPlayer" android:label="VideoView VideoPlayer"> <intent-filter> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"> </uses-permission> </manifest> (責任編輯:張京晶) |
在Android中播放音頻和視頻--值得學習
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.