2012-12-19 114 views
1

目前我正在開發一個應用程序,該應用程序應該將視頻下載到其內部存儲器(不幸的是,它們沒有SD卡)並且只是播放它們。 我到目前爲止試過的是:Android,VideoView,內部存儲

標準VideoView,將/data/data/.../file.mp4設置爲路徑 - 沒有工作。 將MediaPlayer與SurfaceView一起使用,使用路徑或文件描述符 - 無效。

什麼,現在我在這裏是VideoView,它具有以下的變化稍微改裝成的版本:

 if(mUri != null) 
     { 
      mMediaPlayer.setDataSource(mContext, mUri); 
     } 
     else 
     { 
      mMediaPlayer.setDataSource(mFd); 
     } 

另外一個setFD方法讓我把我的文件描述符。這比將整個MediaPlayer/SurfaceView放入我的活動中更方便,更清潔 - imo。 的問題如下:

在內部存儲的文件是這樣的創建:

   FileInputStream fis = openFileInput(Downloader.TMP_FILENAME); 
       FileOutputStream fos = openFileOutput(Downloader.FILENAME 
         + ext, Context.MODE_WORLD_READABLE); 
       byte[] buf = new byte[2048]; 
       while (fis.read(buf) > 0) { 
        fos.write(buf); 
       } 
       fis.close(); 
       fos.close(); 
       deleteFile(Downloader.TMP_FILENAME); 
       Log.d(TAG, "Replacement done!"); 

基本上它的讀取臨時文件(因爲我不希望覆蓋當前播放的..但這並不重要),並將其寫入(在onCompletion之後)到新文件中,之後刪除臨時文件。

我已經測試了3個不同的Android版本,也是迄今設備: - 與Android 4.2的Nexus 7 - - 平板電腦採用Android 2.2 HTC感覺採用Android 4.1.2

它根本沒有工作。它播放讓我們說視頻的前100毫秒。聲音彈出彈出和logcat告訴我:

12-19 14:33:48.074: W/MediaPlayer(5560): info/warning (3, 0) 
12-19 14:33:48.074: I/MediaPlayer(5560): Info (3,0) 
12-19 14:33:48.394: E/MediaPlayer(5560): error (1, -1007) 
12-19 14:33:48.394: E/MediaPlayer(5560): Error (1,-1007) 

但我真的不知道這是什麼意思。 我在整個互聯網上搜索過它,我找到的只是「使用WORLD_READABLE,它會解決問題!」或者「只是使用文件描述符,似乎不關心權限!」。但對我而言,這並不奏效。

我非常感謝任何幫助。

編輯:

  FileInputStream fid = new FileInputStream((getFilesDir() + "/" 
        + Downloader.FILENAME + ext))); 

      mVideoView.setVideoFD(fid.getFD()); 

我這是怎麼了文件描述符添加到MediaPlayer的。

重新編碼的文件後,這是我得到:

12-19 15:06:45.664: E/MediaPlayer(7616): Unable to to create media player 
12-19 15:06:45.664: W/System.err(7616): java.io.IOException: setDataSourceFD failed.: status=0x80000000 
12-19 15:06:45.664: W/System.err(7616):  at android.media.MediaPlayer.setDataSource(Native Method) 
12-19 15:06:45.664: W/System.err(7616):  at android.media.MediaPlayer.setDataSource(MediaPlayer.java:976) 

這是我從我的網絡服務器下載:

Log.i(TAG, "Opening remote connection to " + mFile.getHost() 
       + mFile.getPath()); 
     URLConnection c = mFile.openConnection(); 
     c.connect(); 
     final long lastModified = c.getLastModified(); 
     final String mExtension; 
     if (c.getHeaderField("Content-Disposition") != null) { 
      final String mFilename = c 
        .getHeaderField("Content-Disposition").split("=")[1]; 
      Log.i("Downloader", "Filename is " + mFilename 
        + ", split length is " + mFilename.split("\\.").length); 
      mExtension = mFilename.split("\\.")[mFilename 
        .split("\\.").length - 1]; 
     } else { 
      mExtension = "mp4"; 
     } 

     InputStream is = c.getInputStream(); 

     Log.i(TAG, "Creating temporary local file"); 
     // create local temporary file 
     FileOutputStream fos = mContext.openFileOutput(TMP_FILENAME, 
       Context.MODE_WORLD_READABLE); 

     // start reading 
     byte[] buf = new byte[BUFFER_SIZE]; 
     int bytesRead = 0; 
     int curRead = 0; 
     Log.i(TAG, "Starting download.. to " + TMP_FILENAME); 
     if (mDownloadChangeListener != null) 
      mDownloadChangeListener.onDownloadStart(); 

     while ((curRead = is.read(buf)) > -1) { 
      fos.write(buf); 
      bytesRead += curRead; 
     } 
     Log.i(TAG, "Read " + bytesRead + " bytes in total."); 
     Log.i(TAG, "Download finished!"); 
     // end of stream, tell app to rename file. 
     if (mDownloadChangeListener != null) 
      mDownloadChangeListener.onDownloadFinished(TMP_FILENAME, 
        mExtension); 

     is.close(); 
     fos.close(); 

下載它之後,在onDownloadFinished監聽器,我執行以下代碼:

   FileInputStream fis = openFileInput(Downloader.TMP_FILENAME); 
       FileOutputStream fos = openFileOutput(Downloader.FILENAME 
         + ext, Context.MODE_WORLD_WRITEABLE); 
       byte[] buf = new byte[2048]; 
       while (fis.read(buf) > 0) { 
        fos.write(buf); 
       } 
       fis.close(); 
       fos.close(); 
       deleteFile(Downloader.TMP_FILENAME); 
       Log.d(TAG, "Replacement done!"); 

任何想法可能會出錯?我唯一的另一個想法是,這是因爲內部存儲的東西..但錯誤信息說別的?

回答

1

找到解決方案。每次我測試的方式可能的工作,因爲我收到的所有錯誤從「錯誤下載的媒體文件」來了......

while((curRead = in.read(buf)) { 
    out.write(buf); 
} 

只是缺少一個「0,curRead」 - 現在所有工作。這顯然是因爲read()總是可以返回小於BUFFER_SIZE的值,然後將0字節寫入其餘的東西中...

謝謝!

1

錯誤-1007代表MEDIA_ERROR_MALFORMED。這意味着您嘗試播放的文件不符合官方文檔中規定的文件規範。您收到的媒體或您的保存方法有問題。

就我個人而言,您保存它的方法對我來說看起來很好,所以我猜測源文件本身就是問題所在。

+0

感謝您的回答。這是我從網上下載它的方式:URLConnection c = mFile.openConnection(); c.connect(); InputStream is = c.getInputStream();然後簡單地讀/寫到另一個Stream ..我會嘗試重新編碼它以匹配Android標準,即使是我認爲我已經這樣做了。 – damian

+0

Mh不知道是否因爲我重新編碼了示例文件,但現在得到:12-19 15:06:45.664:W/System.err(7616):java.io.IOException:setDataSourceFD失敗:狀態= 0x80000000 – damian

+0

這似乎是一個常見的錯誤,也涉及到文件格式:http://stackoverflow.com/questions/9657280/mediaplayer-setdatasource-causes-ioexception-for-valid-file和http://stackoverflow.com/questions/9625680/mediaplayer-setdatasource-better-to-use-path-or-filedescriptor –