2015-10-07 63 views
0

我有一個相當奇怪的問題。我正在使用Xamarin框架編寫一個Android應用程序,並且我也有一個iOS版本的相同應用程序,也是用Xamarin編寫的。在應用程序中,用戶可以將照片和視頻發送給他們的朋友,他們的朋友可以在iOS或Android上。這一切都可以正常工作,iPhone上拍攝的視頻可以在Android設備上播放,反之亦然。Android:視頻保存到畫廊將不會播放

我遇到的問題是,當我嘗試以編程方式將視頻保存到Android圖庫時,那麼該視頻無法在圖庫中播放。它似乎確實是複製了它自己的視頻數據,但視頻不知何故無法播放。

我的視頻使用H.264編解碼器編碼爲mp4格式。我相信這在Android中得到了完全支持,就像我說的,當通過應用程序中的VideoView播放視頻時,視頻播放效果會很好。

我用來將視頻複製到畫廊的代碼如下。有沒有人有任何想法我在這裏做錯了?

public static void SaveVideoToGallery(Activity activity, String filePath) { 

    // get filename from path 
    int idx = filePath.LastIndexOf("/") + 1; 
    String name = filePath.Substring(idx, filePath.Length - idx); 

    // set in/out files 
    File inFile = new File(filePath); 
    File outDir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMovies); 
    File outFile = new File(outDir, name); 

    // Make sure the Pictures directory exists. 
    outDir.Mkdirs(); 

    // save the file to disc 
    InputStream iStream = new FileInputStream(inFile); 
    OutputStream oStream = new FileOutputStream(outFile); 
    byte[]data = new byte[iStream.Available()]; 
    iStream.Read(); 
    oStream.Write(data); 
    iStream.Close(); 
    oStream.Close(); 

    // Tell the media scanner about the new file so that it is 
    // immediately available to the user. 
    MediaScannerConnection.ScanFile(
     activity.ApplicationContext, 
     new String[] { outFile.ToString() }, 
     null, 
     null); 
} 

注:我知道這一切都是在C#中,但請記住,所有的Xamarin框架所做的就是提供一個API,以原生的Android方法。我使用的所有東西都是Java或Android支持的類/函數。

謝謝!

回答

1

你的問題是在這個代碼片段:

byte[]data = new byte[iStream.Available()]; 
iStream.Read(); 
oStream.Write(data); 

這裏有幾個問題:

  • 你永遠不讀取文件內容到data緩衝區; iStream.Read()只會讀取一個字節並將其作爲整數返回。
  • new byte[iStream.Available()]將僅分配可用於讀取而沒有阻塞的數據字節的數量。這不是完整的文件。請參閱available方法的文檔。
  • oStream.Write(data)寫出一個垃圾塊的數據,因爲沒有任何東西會讀入它。

最終的結果是輸出的視頻文件只是一個空的數據塊,因此爲什麼畫廊不能使用它。

修復它的讀取從文件流數據,然後寫他們到輸出文件:

int bytes = 0; 
    byte[] data = new byte[1024]; 
    while ((bytes = iStream.Read(data)) != -1) 
    { 
     oStream.Write (data, 0, bytes); 
    } 

全樣本:

public static void SaveVideoToGallery(Activity activity, String filePath) { 

    // get filename from path 
    int idx = filePath.LastIndexOf("/") + 1; 
    String name = filePath.Substring(idx, filePath.Length - idx); 

    // set in/out files 
    File inFile = new File(filePath); 
    File outDir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryMovies); 
    File outFile = new File(outDir, name); 

    // Make sure the Pictures directory exists. 
    outDir.Mkdirs(); 

    // save the file to disc 
    InputStream iStream = new FileInputStream(inFile); 
    OutputStream oStream = new FileOutputStream(outFile); 

    int bytes = 0; 
    byte[] data = new byte[1024]; 
    while ((bytes = iStream.Read(data)) != -1) 
    { 
     oStream.Write (data, 0, bytes); 
    } 

    iStream.Close(); 
    oStream.Close(); 

    // Tell the media scanner about the new file so that it is 
    // immediately available to the user. 
    MediaScannerConnection.ScanFile(
     activity.ApplicationContext, 
     new String[] { outFile.ToString() }, 
     null, 
     null); 
} 
+0

好是啊,我在想,比表面積爲奇數時我寫了它,但我正在從Android文檔中學習一個例子,所以只是假定它是正確的。我試過了,現在它完美的工作,所以謝謝你的幫助和出色的信息。儘管我有一個問題。如果「new byte [1024]」這一行創建了一個大小爲1024字節的字節數組,那麼它如何能夠保存超過1024個字節的數據?可能是一個愚蠢的問題,但我現在很好奇。 –

+0

根本不是一個愚蠢的問題,1024是一個臨時緩衝區,它接受一小塊'iStream'文件,然後將它附加到'oStream'。它會根據需要多次重複使用,以複製整個文件。 – matthewrdev

+1

啊,我明白了,每次傳遞數據需要1024個塊,直到完成。說得通。謝謝哥們! –