我使用一些技巧来尝试当它被写入到磁盘中读取的AVAssetWriter的原始输出。 当我通过连接将其重组的单个文件,生成的文件是字节作为AVAssetWriter的输出文件相同的确切数目。 然而,重组的文件不会在QuickTime播放或因为数据损坏的FFmpeg解析。 这里有几个字节,并且已经改变,使生成的文件无法使用。 我想这是每一次读的EOF边界上发生的,但它是不相符的腐败。
我计划最终使用类似下面的代码从编码器解析出单独的H.264 NAL单元打包它们,并将它们发送RTP,但是如果我不能信任的数据从磁盘读取我可能必须使用另一种解决方案。
是否有此数据损坏的解释/修复? 以及是否有你如何解析NAL单元打包在RTP中发现的任何其他资源/链接?
全部代码在这里: AVAppleEncoder.m
// Modified from
// http://www.davidhamrick.com/2011/10/13/Monitoring-Files-With-GCD-Being-Edited-With-A-Text-Editor.html
- (void)watchOutputFileHandle
{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
int fildes = open([[movieURL path] UTF8String], O_EVTONLY);
source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,fildes,
DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE,
queue);
dispatch_source_set_event_handler(source, ^
{
unsigned long flags = dispatch_source_get_data(source);
if(flags & DISPATCH_VNODE_DELETE)
{
dispatch_source_cancel(source);
//[blockSelf watchStyleSheet:path];
}
if(flags & DISPATCH_VNODE_EXTEND)
{
//NSLog(@"File size changed");
NSError *error = nil;
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingFromURL:movieURL error:&error];
if (error) {
[self showError:error];
}
[fileHandle seekToFileOffset:fileOffset];
NSData *newData = [fileHandle readDataToEndOfFile];
if ([newData length] > 0) {
NSLog(@"newData (%lld): %d bytes", fileOffset, [newData length]);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
NSString *movieName = [NSString stringWithFormat:@"%d.%lld.%d.mp4", fileNumber, fileOffset, [newData length]];
NSString *path = [NSString stringWithFormat:@"%@/%@", basePath, movieName];
[newData writeToFile:path atomically:NO];
fileNumber++;
fileOffset = [fileHandle offsetInFile];
}
}
});
dispatch_source_set_cancel_handler(source, ^(void)
{
close(fildes);
});
dispatch_resume(source);
}
以下是我已经发现了一些类似的问题,但不完全回答我的问题:
- 获取PTS从原料H264 MDAT通过iOS的AVAssetWriter产生
- 流媒体视频从iPhone
- 从的QuickTime MOV文件的解析H.264 NAL单元
- 实时音频/视频流从iPhone到另一个设备(浏览器或iPhone)
当我终于想出解决办法,我会发布一个开放源码库,以协助人们谁试图做到这一点在未来。
谢谢!
更新:腐败不会在EOF边界发生。 这似乎是文件的部分被重新写入后finishWriting
被调用。 第一个文件是在4KB分块,所以面积变化不是EOF边界附近的任何地方。 这似乎当要接近新的“MOOV”元素损坏以及movieFragmentInterval
启用。
在右边的左边,破碎的文件正确的文件。