NSFileHandle 从视频文件中读取损坏的数据

Posted

技术标签:

【中文标题】NSFileHandle 从视频文件中读取损坏的数据【英文标题】:NSFileHandle reading corrupt data from Video file 【发布时间】:2014-08-01 20:43:53 【问题描述】:

我正在使用NSFileHandle 来获取正在录制的视频的数据。

它在通知方面工作得很好,我收到了使用NSFileHandleDataAvailableNotification 的通知。问题是视频文件最终不起作用。

每次将原始文件与使用 NSFileHandle 数据创建的文件进行比较时,总是只有几个字节是错误的,这意味着 NSFileHandle 读取错误。

这就是我添加数据的方式

-(void) gotData: (NSNotification *) not
    NSFileHandle *handle    = not.object;
    NSData *data            = [handle availableData];

    if(data.length)
        NSLog(@"got %d", data.length);
        [test appendData: data];
        [handle waitForDataInBackgroundAndNotify];
    else
        NSLog(@"Ended");
        [[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleDataAvailableNotification object: handle];
    

这就是我最终写入数据的方式:

[test writeToFile:[NSTemporaryDirectory() stringByAppendingPathComponent:@"x.mp4"] atomically:YES];

当在原始文件和来自 NSFileHandle 的文件之间进行 diff 时,这里的字节是错误的(即使两者的大小完全相同):

我对这种奇怪的行为一无所知,如果您遇到类似的问题,我希望您能提供帮助。

【问题讨论】:

【参考方案1】:

我要冒昧地说,NSFileHandle 不可能给你不正确的数据。我认为正在发生的是数据实际上正在被更改(由正在写出它的程序)你得到数据之后。

我不知道你到底想要完成什么,所以我不能提出更好的方法。

我有一些类似的代码从另一个进程正在写出的文件中读取数据,只有我的使用readabilityHandler 而不是NSFileHandleDataAvailableNotification。我没有太多理由相信这会解决您的问题,但值得一试。我知道您可能会遇到NSNotification 的线程问题,所以这可能是值得关注的。

您也许应该使用[NSFileHandle offsetInFile](并根据收到的数据与您的预期位置进行比较)来检查事情是否正在倒带或其他什么。

【讨论】:

我很确定这正是正在发生的事情,因为我正在读取正在写入的文件,当它结束时,我正在写入常规数据和从 NSFileHandle 读取的数据和然后才比较它们。文件将在其中更改并且仅针对这 5-6 个字节... @ShaiMishali 如果它只是改变了 5 或 6 个字节,那么我只能推断这些字节正在改变,因为它们代表了(实际)视频数据的 length(随着时间的推移而上升)。 随着视频变长,更多字节发生变化......我认为这与长度没有任何关系,因为这些字节不包含数值......我唯一能想到的是EXIF ... @ShaiMishali 你可能是对的,因为我现在看到 moov 标识符正在发生变化。用更多想法更新我的答案。

以上是关于NSFileHandle 从视频文件中读取损坏的数据的主要内容,如果未能解决你的问题,请参考以下文章

NSFileManager和NSFileHandle

带有流式视频或 NSFileHandle 的 AVPlayer

NSFileHandle类和NSFileManager,追加数据的操作

如何从 NSFileHandle * 获取 FILE *?

如何在c中读取二进制文件? (视频、图像或文本)

从 Qt 中杀死 ffmpeg 会导致视频文件损坏