2

我正在尝试创建一个供内部使用的 Mac App,它获取用户指定的电影文件,将其转换为特定格式并将每一帧作为图像保存在硬盘上。我已经完成了转换部分,使用了很棒的 Handbrake CLI。

现在我试图找到一种方法将每一帧保存为图像,但我找不到这样做的方法。

似乎 ffmpeg 有一个命令可以将帧提取到图像中。以下将单个帧拉入五秒钟:

ffmpeg -i "infile.mp4" -r 1 -ss 00:00:05 -t 00:00:01 -vframes 1 -f image2 -y "image.jpg"

但是,我宁愿使用 QTKit 或 Handbrake CLI,所以我不必将 ffmpeg 和 Handbrake 都添加到应用程序中。

任何想法将不胜感激!

4

2 回答 2

3

试试这个(用视频中每秒的帧数替换 25)

ffmpeg -i infile.mp4 -r 25 -f image2 /tmp/image-%4d.jpg

然后使用 NSTask 从您的 xcode 项目中运行此命令

下载 FFMPEG O.11.1 for mac osx

下载适用于 mac osx 的 FFMPEG git 版本

于 2012-10-12T19:33:57.703 回答
2

所以,在他们的 IRC 频道讨论之后,我确定你不能用 Handbrake 做到这一点。

但是,这是使用 ffmpeg 的一种相对轻松的方式:

NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
outputPipe = [NSPipe pipe];
taskOutput = [outputPipe fileHandleForReading];
current_task = [[NSTask alloc] init];

NSString *resourcePath = [[NSBundle mainBundle] resourcePath];

NSString *stillName = [NSString stringWithFormat:@"%@_still%d.png", [MY_FILE substringToIndex:([draggedFile length]-4)], MY_STILL_NUMBER];

[current_task setLaunchPath: [NSString stringWithFormat:@"%@/ffmpeg", resourcePath]];

// save just frame at current time
// by leaving -ss before the -i, we enable direct indexing within ffmpeg, which saves a still in about a second, rather than a minute or so on a long video file
NSArray *arguments = [NSArray arrayWithObjects:@"-ss", currentFrameTime, @"-i", draggedFile, @"-vframes", @"1", @"-f", @"image2", stillName, nil];

[current_task setArguments:arguments];
[current_task setStandardInput:[NSPipe pipe]];
[current_task setStandardOutput:outputPipe];
[current_task setStandardError:outputPipe];

[defaultCenter addObserver:self selector:@selector(saveTaskCompleted:) name:NSTaskDidTerminateNotification object:current_task];

[current_task launch];
[taskOutput readInBackgroundAndNotify];

所以,我正在使用 Handbrake 任务(转换视频),然后使用另一个任务来保存静止图像。我可以只使用 ffmpeg,但我喜欢 Handbrake,所以我会以这种方式利用 2。

希望这可以帮助那里的任何人。

于 2012-10-23T11:24:36.837 回答