1. 程式人生 > >MediaPlayer(4024): error (1, -2147483648)解決辦法

MediaPlayer(4024): error (1, -2147483648)解決辦法

遇到此問題setDataSource用FileDescriptor代替即可,如下面紅色的程式碼。

MediaPlayer player = new MediaPlayer();
   try {
    Log.d(TAG, recorder.getFileName());
    player.setAudioStreamType(AudioManager.STREAM_RING);
    FileInputStream fis = new FileInputStream(new File(filePath));
    player.setDataSource(fis.getFD());


    player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
     @Override
     public void onCompletion(MediaPlayer mp) {
      mp.stop();
      mp.release();
     }
    });
    player.setLooping(false);
    player.prepare();
    player.setVolume(1f, 1f);
    player.start();
   } catch (IllegalArgumentException e) {
    e.printStackTrace();
   } catch (SecurityException e) {
    e.printStackTrace();
   } catch (IllegalStateException e) {
    e.printStackTrace();
   } catch (IOException e) {
    e.printStackTrace();
   }

將媒體檔案push到sdcard目錄

啟動模擬器後,在DDMS透檢視中,選擇File Explorer,選擇/mnt/sdcard目錄,點選檢視工具欄的+,將選擇的檔案push進去。
注:如果push失敗,提示Read-Only File System,請將sdcard目錄授以讀+寫許可權,命令為

Python程式碼  收藏程式碼
  1. $ adb shell mount -o remount rw /  

使用ls -l檢視指定目錄下的檔案及資料夾詳細資訊,許可權資訊在第一列。如

Python程式碼  收藏程式碼
  1. $ adb shell  
  2. # ls -l /mnt/sdcard  

 
注:在File Explorer中,已經列出了各資料夾和檔案的許可權。如果sdcard沒有讀寫許可權,請先授權。

使用VideoView渲染媒體

為什麼要用VideoView?VideoView使用起來簡單,而且封裝了播放器,如播放錯誤,android會給出警告提示 ,不需要使用者程式設計處理這些異常。程式碼如下:

Java程式碼  收藏程式碼
  1. viedoView.setVideoPath(filePath);//filePath = “/sdcard/test.mp3”;  
  2. videoView.start();  

 
簡單是簡單,但不幸的是,如果媒體源沒問題,但播放異常的話,定位就複雜一些了。
注:啟動後,系統提示”對不起,該視訊無法播放“,在LogCat中看到MediaPlayer和VideoView都指列印了一條error(1, -2147483648)的LOG。
導致此錯誤的典型原因有:
1,檔案路徑不對,如目錄錯誤,不存在的URL及URI
2,媒體檔案錯誤,或不支援的格式
3,缺少許可權
經過debug,發現問題出在VideoView#openVidio的mMediaPlayer.prepareAsync();處。
prepare失敗了,prepare的方法有兩個,還有一個是prepare(),官網給的說明,它位的不同之處是,前者是非同步執行。但個人認為,應該還有一個不同之處,前者不會丟擲異常。

使用MediaPlayer

使用MediaPlayer也很簡單。如下程式碼所示:

Java程式碼  收藏程式碼
  1. MediaPlayer mp = new MediaPlayer();  
  2. mp.setDataSource(this,uri);  
  3. mp.prepare();// 使用mp.prepareAsync(),不會丟擲異常,但有錯誤LOG,為error(38,0);  
  4. mp.start();  

 
注:對上面那個無法播放的問題,可以在prepare()處捕獲到IO異常:

Java程式碼  收藏程式碼
  1. java.io.IOException: Prepare failed.: status=0x1  

對於此異常,有網友說模擬器對mp3支援不好,建議將mp3換成ogg格式再試。也有的說,使用類似以下方法 Java程式碼  收藏程式碼
  1. //   FileInputStream fis = new FileInputStream(file);  
  2. //   mp.setDataSource(fis.getFD());   

 
前者我沒有試過,如果有度過的,請告訴我結果。我使用的是後者,發現在建立輸入流時,丟擲了FileNotFoundException:file not exists(permission denied),關鍵在permission denied這句,應該是缺少許可權,但媒體檔案是有許可權的,sdcard目錄沒有,於是給sdcard目錄授以最大許可權。

Python程式碼  收藏程式碼
  1. $ adb shell  
  2. # chmod 777 /mnt/sdcard  

討論

討論1:在準備工作中,已經使用

Python程式碼  收藏程式碼
  1. $ adb shell mount -o remount rw /  

Python程式碼  收藏程式碼
  1. $ adb shell mount -o remount 777 /  

給目錄授權過了,但為何sdcard目錄還是無許可權?
討論2:Android對網路播放是否存在bug,對於本地可以正常播放的3gp,mp4等視訊,放到伺服器中使用http get方式進行網路播放,卻只有少數片源可以播放,大多數在prepare()時就丟擲了異常。