Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android多媒體學習七:訪問網絡上的Audio對應的M3U文件,實現網絡音頻流的播放

Android多媒體學習七:訪問網絡上的Audio對應的M3U文件,實現網絡音頻流的播放

編輯:Android開發實例

Android中提供了對網絡上流媒體的支持,我們可以使用MediaPlayer類來播放一個網絡上的音頻文件。

但是網絡上的站點並不建議我們直接訪問流,我們需要獲取他提供的M3U文件,根據M3U文件來實現流的獲取。

M3U是音頻流地址索引文件,相當於播放列表。

本文通過實例演示,Android中如何訪問網絡上的M3U文件,實現網絡音頻文件的播放。

本文包含三個部分:

1、根據用戶輸入的M3U文件的Url,訪問網絡,獲取該M3U文件

2、對獲取到的M3U文件進行解析,Android中並沒有提供現成的方法來解析M3U文件

3、顯示解析結果,並利用MediaPlayer來播放列表

代碼如下:

1、HttpConnect類:封裝網絡訪問

 

  1. package demo.camera;  
  2. import java.io.BufferedReader;  
  3. import java.io.InputStream;  
  4. import java.io.InputStreamReader;  
  5. import org.apache.http.HttpResponse;  
  6. import org.apache.http.HttpStatus;  
  7. import org.apache.http.client.HttpClient;  
  8. import org.apache.http.client.methods.HttpGet;  
  9. import org.apache.http.impl.client.DefaultHttpClient;  
  10. import android.util.Log;  
  11. /**  
  12.  * 給類提供訪問網絡的方法  
  13.  * @author Administrator  
  14.  *  
  15.  */ 
  16. public final class HttpConnect {  
  17.       
  18.     /**  
  19.      * 利用HttpClient獲取指定的Url對應的HttpResponse對象  
  20.      * @param url  
  21.      * @return  
  22.      */ 
  23.     public static HttpResponse getResponseFromUrl(String url){  
  24.         try {  
  25.             HttpClient client = new DefaultHttpClient();  
  26.             HttpGet get = new HttpGet(url);  
  27.             Log.v("URI : ", get.getURI().toString());  
  28.             HttpResponse response = client.execute(get);  
  29.             if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){  
  30.                 return response;  
  31.             }  
  32.         } catch (Exception e) {  
  33.             // TODO: handle exception  
  34.             e.printStackTrace();  
  35.         }  
  36.         return null;  
  37.     }  
  38.       
  39.     /**  
  40.      * 利用HttpClient獲取指定Url對應的字符串對象  
  41.      * @param url  
  42.      * @return  
  43.      */ 
  44.     public static String getStringFromUrl(String url){  
  45.         try {  
  46.             StringBuilder result = new StringBuilder();  
  47.             HttpResponse res = HttpConnect.getResponseFromUrl(url);  
  48.             if(res != null){  
  49.                 InputStream is = res.getEntity().getContent();  
  50.                 BufferedReader reader = new BufferedReader(new InputStreamReader(is));  
  51.                 String line = "";  
  52.                 while((line = reader.readLine()) != null){  
  53.                     result.append(line);  
  54.                 }  
  55.                 is.close();  
  56.                 return result.toString();  
  57.             }  
  58.         } catch (Exception e) {  
  59.             // TODO: handle exception  
  60.         }  
  61.           
  62.         return null;  
  63.     }  
  64. }  

2、M3UParser類:解析M3U文件

 

  1. package demo.camera;  
  2. import java.io.BufferedReader;  
  3. import java.io.InputStream;  
  4. import java.io.InputStreamReader;  
  5. import java.util.ArrayList;  
  6. import java.util.List;  
  7. import org.apache.http.HttpResponse;  
  8. /**  
  9.  * 該類提供對M3U文件的解析  
  10.  * @author Administrator  
  11.  *  
  12.  */ 
  13. public final class M3UParser {  
  14.       
  15.     /**  
  16.      * 從指定的Url進行解析,返回一個包含FilePath對象的列表  
  17.      * FilePath封裝每一個Audio路徑。  
  18.      * @param url  
  19.      * @return  
  20.      */ 
  21.     public static List<FilePath> parseFromUrl(String url){  
  22.         List<FilePath> resultList = null;  
  23.         HttpResponse res = HttpConnect.getResponseFromUrl(url);  
  24.         try {  
  25.             if(res != null){  
  26.                 resultList = new ArrayList<M3UParser.FilePath>();  
  27.                 InputStream in = res.getEntity().getContent();  
  28.                 BufferedReader reader = new BufferedReader(new InputStreamReader(in));  
  29.                 String line = "";  
  30.                 while((line = reader.readLine()) != null){  
  31.                     if(line.startsWith("#")){  
  32.                         //這裡是Metadata信息  
  33.                     }else if(line.length() > 0 && line.startsWith("http://")){  
  34.                         //這裡是一個指向的音頻流路徑  
  35.                         FilePath filePath = new FilePath(line);  
  36.                         resultList.add(filePath);  
  37.                     }  
  38.                 }  
  39.                 in.close();  
  40.             }  
  41.         } catch (Exception e) {  
  42.             e.printStackTrace();  
  43.         }  
  44.         return resultList;  
  45.     }  
  46.       
  47.     /**  
  48.      * 返回List<String>類型  
  49.      * @param url  
  50.      * @return  
  51.      */ 
  52.     public static List<String> parseStringFromUrl(String url){  
  53.         List<String> resultList = null;  
  54.         HttpResponse res = HttpConnect.getResponseFromUrl(url);  
  55.         try {  
  56.             if(res != null){  
  57.                 resultList = new ArrayList<String>();  
  58.                 InputStream in = res.getEntity().getContent();  
  59.                 BufferedReader reader = new BufferedReader(new InputStreamReader(in));  
  60.                 String line = "";  
  61.                 while((line = reader.readLine()) != null){  
  62.                     if(line.startsWith("#")){  
  63.                         //這裡是Metadata信息  
  64.                     }else if(line.length() > 0 && line.startsWith("http://")){  
  65.                         //這裡是一個指向的音頻流路徑  
  66.                         resultList.add(line);  
  67.                     }  
  68.                 }  
  69.                 in.close();  
  70.             }  
  71.         } catch (Exception e) {  
  72.             e.printStackTrace();  
  73.         }  
  74.         return resultList;        
  75.     }  
  76.       
  77.       
  78.     //解析後的實體對象  
  79.     static class FilePath{  
  80.           
  81.         private String filePath;  
  82.           
  83.         public FilePath(String filePath){  
  84.             this.filePath = filePath;  
  85.         }  
  86.         public String getFilePath() {  
  87.             return filePath;  
  88.         }  
  89.         public void setFilePath(String filePath) {  
  90.             this.filePath = filePath;  
  91.         }  
  92.           
  93.           
  94.     }  
  95. }  

3、InternetAudioDemo類:顯示解析列表嗎,並實現播放

 

  1. package demo.camera;  
  2. import java.io.IOException;  
  3. import java.util.List;  
  4. import demo.camera.M3UParser.FilePath;  
  5. import android.app.Activity;  
  6. import android.app.ListActivity;  
  7. import android.app.ProgressDialog;  
  8. import android.media.MediaPlayer;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.view.inputmethod.InputMethodManager;  
  12. import android.widget.ArrayAdapter;  
  13. import android.widget.Button;  
  14. import android.widget.EditText;  
  15. import android.widget.ListAdapter;  
  16. import android.widget.Toast;  
  17. /**  
  18.  * Android支持播放網絡上的Audio  
  19.  * 訪問網絡上的Audio,我們通過Http需要獲取音頻流  
  20.  * 這可能要涉及到ICY協議。ICY對Http協議進行了擴展  
  21.  * 然而,網絡上的站點,往往並不允許我們直接訪問其音頻流  
  22.  * 我們需要一種中間文件來指向我們需要的音頻流的地址,以使第三方的軟件可以播放。  
  23.  * 對於ICY流來說,其就是一個PLS文件或者一個M3U文件  
  24.  * PLS對應的MIME類型為:audio/x-scpls  
  25.  * M3U對應的MIME類型為:audio/x-mpegurl  
  26.  *   
  27.  * 雖然Android提供了對ICy流的支持,但是其並沒有提供現成的方法來解析M3U或PLS文件  
  28.  * 所以,為了播放網絡上的音頻流,我們需要自己實現這些文件的解析  
  29.  * M3U文件其實就是一個音頻流的索引文件,他指向要播放的音頻流的路徑。  
  30.  * @author Administrator  
  31.  *  
  32.  */ 
  33. public class InternetAudioDemo extends ListActivity {  
  34.       
  35.     private Button btnParse, btnPlay, btnStop;  
  36.       
  37.     private EditText editUrl;  
  38.       
  39.     private MediaPlayer player;  
  40.       
  41.     private List<String> pathList;  
  42.       
  43.     private int currPosition = 0; //記錄當前播放的媒體文件的index  
  44.       
  45.     //private ProgressDialog progress;  
  46.       
  47.     public void onCreate(Bundle savedInstanceState){  
  48.         super.onCreate(savedInstanceState);  
  49.         setContentView(R.layout.internet_audio);  
  50.           
  51.         btnParse = (Button)this.findViewById(R.id.btn_parse);  
  52.         btnPlay = (Button)this.findViewById(R.id.btn_start);  
  53.         btnStop = (Button)this.findViewById(R.id.btn_end);  
  54.           
  55.         editUrl = (EditText)this.findViewById(R.id.edit_url);  
  56.         editUrl.setText("http://pubint.ic.llnwd.net/stream/pubint_kmfa.m3u");  
  57. //      InputMethodManager imm = (InputMethodManager)this.getSystemService(INPUT_METHOD_SERVICE);  
  58. //      imm.showSoftInput(editUrl, InputMethodManager.SHOW_IMPLICIT);  
  59.         btnPlay.setEnabled(false);  
  60.         btnStop.setEnabled(false);  
  61.           
  62.         player = new MediaPlayer();  
  63.         player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {  
  64.               
  65.             @Override 
  66.             public void onCompletion(MediaPlayer player) {  
  67.                 // 這個方法當MediaPlayer的play()執行完後觸發  
  68.                 player.stop();  
  69.                 player.reset();  
  70.                 if(pathList.size() > currPosition+1){  
  71.                     currPosition++; //轉到下一首  
  72.                     prepareToPlay();  
  73.                 }  
  74.             }  
  75.         });  
  76.           
  77.         player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {  
  78.               
  79.             @Override 
  80.             public void onPrepared(MediaPlayer arg0) {  
  81.                 // 這個方法當MediaPlayer的prepare()執行完後觸發  
  82.                 btnStop.setEnabled(true);  
  83.                 player.start();  
  84.                   
  85.                 //當一曲播放完後,執行onCompletionListener的onCompletion方法  
  86.             }  
  87.         });  
  88.           
  89.     }  
  90.       
  91.     private void prepareToPlay(){  
  92.         try {  
  93.             //獲取當前音頻流的路徑後我們需要通過MediaPlayer的setDataSource來設置,然後調用prepareAsync()來完成緩存加載  
  94.             String path = pathList.get(currPosition);  
  95.             player.setDataSource(path);  
  96.             //之所以使用prepareAsync是因為該方法是異步的,因為訪問音頻流是網絡操作,在緩沖和准備播放時需要花費  
  97.             //較長的時間,這樣用戶界面就可能出現卡死的現象  
  98.             //該方法執行完成後,會執行onPreparedListener的onPrepared()方法。  
  99.             player.prepareAsync();  
  100.               
  101.         } catch (IllegalArgumentException e) {  
  102.             // TODO Auto-generated catch block  
  103.             e.printStackTrace();  
  104.         } catch (IllegalStateException e) {  
  105.             // TODO Auto-generated catch block  
  106.             e.printStackTrace();  
  107.         } catch (IOException e) {  
  108.             // TODO Auto-generated catch block  
  109.             e.printStackTrace();  
  110.         }         
  111.     }  
  112.       
  113.       
  114.     public void onClick(View v){  
  115.         int id = v.getId();  
  116.         switch(id){  
  117.         case R.id.btn_parse:  
  118.             //完成解析  
  119. //          progress = ProgressDialog.show(this, "提示", "正在解析,請稍後...");  
  120. //          progress.show();  
  121.             String url = null;  
  122.             if(editUrl.getText() != null){  
  123.                 url = editUrl.getText().toString();  
  124.             }  
  125.             if(url != null && !url.trim().equals("")){  
  126.                 pathList = M3UParser.parseStringFromUrl(url);  
  127.                 ListAdapter adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, pathList);  
  128.                 this.setListAdapter(adapter);  
  129.                 btnPlay.setEnabled(true);  
  130.             }else{  
  131.                 Toast.makeText(this, "請輸入正確的M3U文件訪問地址", Toast.LENGTH_LONG).show();  
  132.             }  
  133.               
  134.             break;  
  135.         case R.id.btn_start:  
  136.             //這裡播放是從第一個開始  
  137.             btnPlay.setEnabled(false);  
  138.             btnParse.setEnabled(false);  
  139.             this.currPosition = 0;  
  140.             if(pathList != null && pathList.size() > 0){  
  141.                   
  142.                 prepareToPlay();  
  143.                   
  144.             }  
  145.             break;  
  146.         case R.id.btn_end:  
  147.             player.pause();  
  148.             btnPlay.setEnabled(true);  
  149.             btnStop.setEnabled(false);  
  150.             break;  
  151.         default:  
  152.             break;  
  153.               
  154.         }  
  155.     }  
  156. }  

4、需要在清單文件中加入INTERNET權限。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved