InvalidCastException inside MonoTouch's AVFoundation.AVA

本文关键字:AVFoundation AVA inside MonoTouch InvalidCastException | 更新日期: 2023-09-27 18:28:40

我正在尝试一个非常简单的程序:使用AVFoundation加载资源视频,并将视频帧字节作为OpenGL纹理获取。

一般流程非常简单:

  • 我将视频加载到AVAsset
  • 然后我将视频音轨放入AVAssetReaderTrackOutput
  • 我把它插入AVAssetReader
  • 我开始阅读
  • 对于每一个视频帧,我得到一个CMSampleBuffer,从中得到CVPixelBuffer
  • 然后我锁定CVPixelBuffer,并用GL.TexImage2D将其上传到OpenGL中

它在模拟器中运行得很好,但当我在实际设备中尝试时,第一步就会出现以下错误:

System.InvalidCastException: Cannot cast from source type to destination type.
  at MonoTouch.AVFoundation.AVAsset.FromUrl (MonoTouch.Foundation.NSUrl url) [0x00011] in /Developer/MonoTouch/Source/monotouch/src/AVFoundation/AVAsset.g.cs:231
  at MyTestApp.EAGLView.LoadVideo () [0x00033] in /Volumes/Shared/MyTestApp/MyTestApp/EAGLView.cs:191

引发异常的代码如下所示:

private AVAsset videoAsset;
private AVAssetReaderTrackOutput videoReaderOutput;
private AVAssetReader videoReader;
private void LoadVideo()
{
    var videoPath = NSBundle.MainBundle.PathForResource("video", "mp4");
    var videoURL = NSUrl.FromFilename(videoPath);
    Console.WriteLine ("Loading from " + videoURL.ToString ());
    object videoAssetRaw = AVAsset.FromUrl(videoURL); // Exception thrown here
    videoAsset = videoAssetRaw as AVAsset;
    var tracks = videoAsset.Tracks;
    NSError error;
    AVAssetTrack videoTrack = tracks[0];
    AVVideoSettings settings = new AVVideoSettings ();
    settings.PixelFormat = CVPixelFormatType.CV32BGRA;
    videoReaderOutput = AVAssetReaderTrackOutput.FromTrack(videoTrack, settings.ToDictionary());
    videoReader = new AVAssetReader (videoAsset, out error);
    videoReader.AddOutput (videoReaderOutput);
    videoReader.StartReading ();
}

我直接将其放入object而不是AVAsset,只是为了确保InvalidCastException不会被抛出到我这边,但当异常读取时,它被抛出到AVAsset.g.cs的第231行,而我没有。

视频文件是作为"BundleResource"构建的,我使用的是最新版本的xamarin(今天早些时候下载)。

有什么想法可能导致这种情况吗?

InvalidCastException inside MonoTouch's AVFoundation.AVA

不如。。。

object videoAssetRaw = AVAsset.FromUrl(videoURL);

尝试。。。

AVUrlAssetOptions options = null;
var asset = new AVUrlAsset (url, options);