Android:保存到图库的视频无法播放

时间:2015-10-07 12:41:04

标签: android xamarin xamarin.ios

我有一个相当奇怪的问题。我正在使用Xamarin框架编写一个Android应用程序,我也有一个同样的应用程序的iOS版本也用Xamarin编写。在应用程序中,用户可以将照片和视频发送给他们的朋友,他们的朋友可以在iOS或Android上。这一切都很好,在iPhone上播放的视频可以在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框架都提供了原生Android方法的API。我使用的所有东西都是Java或Android支持的类/函数。

谢谢!

1 个答案:

答案 0 :(得分:1)

您的问题出现在以下代码段中:

spree

这里有一些问题:

  • 您永远不会将文件内容读入byte[]data = new byte[iStream.Available()]; iStream.Read(); oStream.Write(data); 缓冲区; iStream.Read()只读取一个字节并将其作为整数返回。
  • data只会分配可以无阻塞地读取的数据字节数。它不是完整的文件。请参阅available方法上的文档。
  • new byte[iStream.Available()]写出一个垃圾数据块,因为没有任何内容被读入。

最终结果是输出的视频文件只是一个空数据块,因此图库无法使用它。

修复它从文件流中读取数据,然后将它们写入输出文件:

oStream.Write(data)

完整样本:

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