iOS ffmpeg如何运行命令来修剪远程url视频?

时间:2016-07-23 00:04:29

标签: ios xcode video ffmpeg avfoundation

我最初使用AVFoundation库修剪视频,但它有一个限制,即无法对远程网址执行此操作,仅适用于本地网址。

因此,经过进一步的研究,我找到了ffmpeg库,它可以包含在iOS的Xcode项目中。 我已经测试了以下命令来在命令行上修剪远程视频:

ffmpeg -y -ss 00:00:01.000 -i "http://i.imgur.com/gQghRNd.mp4" -t 00:00:02.000 -async 1 cut.mp4

.mp4从1秒修剪为3秒。这可以通过我的mac上的命令行完美地工作。

我已成功编译并将ffmpeg库包含到xcode项目中,但不确定如何继续进行。

现在我想弄清楚如何使用ffmpeg库在iOS应用上运行此命令。我怎么能这样做?

如果你能指出一些有用的方向,我真的很感激!如果我能使用您的解决方案解决问题,我将奖励一笔赏金(在2天内给予我选项)。

1 个答案:

答案 0 :(得分:0)

我对此有所了解。但是,我在iOS上的exp非常有限,并且不确定我的想法是否是最佳方式:

据我所知,通常无法在iOS上运行cmd工具。也许你必须写一些链接到ffmpeg libs的代码。

以下是所有需要完成的工作:

  1. 打开输入文件并初始化一些ffmpeg上下文。
  2. 获取视频流并寻找您想要的时间戳。这可能很复杂。请参阅ffmpeg tutorial获取一些帮助,或查看this以准确查找和处理麻烦的关键帧。
  3. 解码一些帧。直到帧匹配结束时间戳。
  4. 与上述同时,将帧编码为新文件作为输出。
  5. 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
            }
        }
    }