我對此有一些想法。然而,我在iOS上的exp已經非常有限,不確定我的想法是否是最好的方式:
據我所知,通常不可能在iOS上運行cmd工具。也許你必須編寫一些鏈接到ffmpeg庫的代碼。
這裏需要做的所有工作:
- 打開輸入文件和init一些ffmpeg的背景。
- 獲取視頻流並尋找您想要的時間戳。這可能很複雜。請參閱ffmpeg tutorial獲得一些幫助,或查看this以精確查找並處理麻煩的關鍵幀。
- 解碼一些幀。直到框架匹配結束時間戳。
- 與此同時,將幀編碼爲一個新的文件作爲輸出。
ffmpeg源碼中的示例非常適合瞭解如何執行此操作。
一些也許有用代碼:
av_register_all();
avformat_network_init();
AVFormatContext* fmt_ctx;
avformat_open_input(&fmt_ctx, "http://i.imgur.com/gQghRNd.mp4", NULL, NULL);
avformat_find_stream_info(fmt_ctx, NULL);
AVCodec* dec;
int video_stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);
AVCodecContext* dec_ctx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar)
// If there is audio you need, it should be decoded/encoded too.
avcodec_open2(dec_ctx, dec, NULL);
// decode initiation done
av_seek_frame(fmt_ctx, video_stream_index, frame_target, AVSEEK_FLAG_FRAME);
// or av_seek_frame(fmt_ctx, video_stream_index, timestamp_target, AVSEEK_FLAG_ANY)
// and for most time, maybe you need AVSEEK_FLAG_BACKWARD, and skipping some following frames too.
AVPacket packet;
AVFrame* frame = av_frame_alloc();
int got_frame, frame_decoded;
while (av_read_frame(fmt_ctx, &packet) >= 0 && frame_decoded < second_needed * fps) {
if (packet.stream_index == video_stream_index) {
got_frame = 0;
ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, &packet);
// This is old ffmpeg decode/encode API, will be deprecated later, but still working now.
if (got_frame) {
// encode frame here
}
}
}