AVAssetWriter 在 iPod Touch 第三代 / OS 4.2.1 上开始写入失败

发布于 2024-11-04 02:29:01 字数 3549 浏览 2 评论 0原文

我的应用程序创建一个 mp4 文件。我已经验证我的代码可以在以下设备上运行:

  • iPad (OS 4.3.2)
  • iPhone4 (OS 4.2.1)
  • iPhone 3GS (OS 4.2.1)

..但是在我的 iPod Touch 3rd Gen 上运行时初始化失败操作系统 4.2.1。

这与这里的另一个问题相关,但我在与他不同的iOS设备上看到它是的,我已经在这里包含了我的初始化代码。与另一个问题一样,我尝试了不同的像素格式和比特率,但在调用其 startWriting 函数后, AVAssetWriter 的状态始终更改为 AVAssetWriterStatusFailed

任何想法将不胜感激。我知道可以在此设备上创建 mp4,因为我下载了另一个应用程序,该应用程序在我的代码失败的同一设备上做得很好。

这是进行视频设置的最少代码。

#import "AVFoundation/AVFoundation.h"
#import "AVFoundation/AVAssetWriterInput.h"
#import "AVFoundation/AVAssetReader.h"
#import "Foundation/NSUrl.h"


void VideoSetupTest()
{
    int width = 320;
    int height = 480;

    // Setup the codec settings.
    int nBitsPerSecond = 100000;
    NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   [NSNumber numberWithInt: nBitsPerSecond], AVVideoAverageBitRateKey, 
                                   nil];        

    // Create the AVAssetWriterInput.
    NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                    AVVideoCodecH264, AVVideoCodecKey,
                                    codecSettings, AVVideoCompressionPropertiesKey,
                                    [NSNumber numberWithInt: width], AVVideoWidthKey,
                                    [NSNumber numberWithInt: height], AVVideoHeightKey,
                                    nil];

    AVAssetWriterInput *assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType: AVMediaTypeVideo outputSettings: outputSettings];
    [assetWriterInput retain];

    // Create the AVAssetWriterPixelBufferAdaptor.
    NSDictionary *pixelBufferAdaptorAttribs = [NSDictionary dictionaryWithObjectsAndKeys:
                                               [NSNumber numberWithInt: kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, 
                                               [NSNumber numberWithInt: width], kCVPixelBufferWidthKey,
                                               [NSNumber numberWithInt: height], kCVPixelBufferHeightKey,
                                               nil];
    AVAssetWriterInputPixelBufferAdaptor *pixelBufferAdaptor = [AVAssetWriterInputPixelBufferAdaptor alloc];
    [pixelBufferAdaptor initWithAssetWriterInput: assetWriterInput sourcePixelBufferAttributes: pixelBufferAdaptorAttribs];



    // Figure out a filename.
    NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
    NSString *documentsDirectory = [paths objectAtIndex:0];
    char szFilename[256];
    sprintf( szFilename, "%s/test.mp4", [documentsDirectory UTF8String] );
    unlink( szFilename );
    printf( "Filename:\n%s\n\n", szFilename );


    // Create the AVAssetWriter.
    NSError *pError;
    NSURL *url = [NSURL fileURLWithPath: [NSString stringWithUTF8String: szFilename]];
    AVAssetWriter *assetWriter = [AVAssetWriter alloc];
    [assetWriter initWithURL:url  fileType:AVFileTypeMPEG4  error:&pError];


    // Bind these things together and start!
    assetWriterInput.expectsMediaDataInRealTime = YES;
    [assetWriter addInput:assetWriterInput];


    //
    // ** NOTE: Here's the call where [assetWriter status] starts returning AVAssetWriterStatusFailed
    //          on an iPod 3rd Gen running iOS 4.2.1.
    //
    [assetWriter startWriting];
}

My app creates an mp4 file. I've verified that the code I have works on the following devices:

  • iPad (OS 4.3.2)
  • iPhone4 (OS 4.2.1)
  • iPhone 3GS (OS 4.2.1)

.. but the init fails on my iPod Touch 3rd Gen running OS 4.2.1.

This is related to another question on here, but I'm seeing it on a a different iOS device than he was and I've included my init code here. Like the other question, I've tried different pixel formats as well as bitrates, but the AVAssetWriter's status always changes to AVAssetWriterStatusFailed after calling its startWriting function.

Any ideas would be greatly appreciated. I know that mp4 creation is possible on this device because I've downloaded another app that does it just fine on the same device that my code fails on.

Here is the minimal code to do the video setup.

#import "AVFoundation/AVFoundation.h"
#import "AVFoundation/AVAssetWriterInput.h"
#import "AVFoundation/AVAssetReader.h"
#import "Foundation/NSUrl.h"


void VideoSetupTest()
{
    int width = 320;
    int height = 480;

    // Setup the codec settings.
    int nBitsPerSecond = 100000;
    NSDictionary *codecSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   [NSNumber numberWithInt: nBitsPerSecond], AVVideoAverageBitRateKey, 
                                   nil];        

    // Create the AVAssetWriterInput.
    NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                    AVVideoCodecH264, AVVideoCodecKey,
                                    codecSettings, AVVideoCompressionPropertiesKey,
                                    [NSNumber numberWithInt: width], AVVideoWidthKey,
                                    [NSNumber numberWithInt: height], AVVideoHeightKey,
                                    nil];

    AVAssetWriterInput *assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType: AVMediaTypeVideo outputSettings: outputSettings];
    [assetWriterInput retain];

    // Create the AVAssetWriterPixelBufferAdaptor.
    NSDictionary *pixelBufferAdaptorAttribs = [NSDictionary dictionaryWithObjectsAndKeys:
                                               [NSNumber numberWithInt: kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, 
                                               [NSNumber numberWithInt: width], kCVPixelBufferWidthKey,
                                               [NSNumber numberWithInt: height], kCVPixelBufferHeightKey,
                                               nil];
    AVAssetWriterInputPixelBufferAdaptor *pixelBufferAdaptor = [AVAssetWriterInputPixelBufferAdaptor alloc];
    [pixelBufferAdaptor initWithAssetWriterInput: assetWriterInput sourcePixelBufferAttributes: pixelBufferAdaptorAttribs];



    // Figure out a filename.
    NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
    NSString *documentsDirectory = [paths objectAtIndex:0];
    char szFilename[256];
    sprintf( szFilename, "%s/test.mp4", [documentsDirectory UTF8String] );
    unlink( szFilename );
    printf( "Filename:\n%s\n\n", szFilename );


    // Create the AVAssetWriter.
    NSError *pError;
    NSURL *url = [NSURL fileURLWithPath: [NSString stringWithUTF8String: szFilename]];
    AVAssetWriter *assetWriter = [AVAssetWriter alloc];
    [assetWriter initWithURL:url  fileType:AVFileTypeMPEG4  error:&pError];


    // Bind these things together and start!
    assetWriterInput.expectsMediaDataInRealTime = YES;
    [assetWriter addInput:assetWriterInput];


    //
    // ** NOTE: Here's the call where [assetWriter status] starts returning AVAssetWriterStatusFailed
    //          on an iPod 3rd Gen running iOS 4.2.1.
    //
    [assetWriter startWriting];
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨落成白 2024-11-11 02:29:01

我得出的结论是,第三代 iPod Touch 无法创建 .mp4 视频。这是有道理的 - 为什么在甚至没有相机来捕捉视频的设备上包含视频编码硬件?

让我认为它可以创建 .mp4 视频的原因是我有另一个应用程序能够从我的 iPod Touch 3 创建它们。但是在分析该应用程序的 .mp4 视频后,发现它是实际上是使用 ffmpeg 创建的 H.263(MPEG-4 第 2 部分)视频。 (而 AVFoundation 将创建 H.264 视频(如果它可以在设备上完成)。

I've come to the conclusion that the iPod Touch 3rd Gen just can't create .mp4 videos, period. This would make sense - why include video encoding hardware on a device that doesn't even have a camera to capture videos with?

The thing that was making me think that it could create .mp4 videos was that I had another app that was able to create them from my iPod Touch 3. But upon analyzing that app's .mp4 video, it was actually an H.263 (MPEG-4 part-2) video created with ffmpeg. (Whereas AVFoundation will create H.264 videos if it can do it at all on a device).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文