You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用ffmpeg-next API按起止时间裁剪视频?求示例

使用ffmpeg-next实现视频裁剪(Rust)

ffmpeg-next 并没有提供直接的"裁剪"API,而是通过输入流seek定位起始时间 + 控制输出帧数量/时长的方式实现视频裁剪。下面是一个完整的示例,实现从指定起始时间开始,裁剪指定时长的视频内容,同时支持编译为单个静态二进制文件。

1. 依赖配置

在Cargo.toml中添加ffmpeg-next依赖,启用静态编译特性:

[dependencies]
ffmpeg-next = { version = "0.31", features = ["build", "static", "codec", "format", "filter"] }
  • build:让库自动编译FFmpeg静态库(需确保系统有编译依赖,比如Linux下的build-essential、yasm等)
  • static:强制静态链接,最终生成单个二进制文件

2. 完整裁剪示例代码

use ffmpeg::format::{input, output, Pixel};
use ffmpeg::media::Type;
use ffmpeg::software::scaling::{context::Context, flag::Flags};
use ffmpeg::{codec, frame, Rational};
use std::path::Path;

fn crop_video(input_path: &str, output_path: &str, start_sec: f64, duration_sec: f64) -> Result<(), ffmpeg::Error> {
    // 初始化FFmpeg
    ffmpeg::init().unwrap();

    // 打开输入文件
    let mut ictx = input(&Path::new(input_path))?;
    let input_stream = ictx
        .streams()
        .best(Type::Video)
        .ok_or_else(|| ffmpeg::Error::StreamNotFound)?;
    let stream_index = input_stream.index();

    // 获取视频流的时间基和帧率,计算起始时间戳与目标总帧数
    let time_base = input_stream.time_base();
    let frame_rate = input_stream.rate();
    let start_ts = (start_sec * time_base.0 as f64 / time_base.1 as f64) as i64;
    let total_frames = (duration_sec * frame_rate.0 as f64 / frame_rate.1 as f64) as usize;

    // 定位输入流到起始时间
    ictx.seek(start_ts, stream_index)?;

    // 初始化解码器与输出流
    let mut decoder = input_stream.codec().decoder().video()?;
    let mut octx = output(&Path::new(output_path))?;
    let mut ost = octx.add_stream(decoder.codec())?;
    ost.set_time_base(time_base);
    ost.set_rate(frame_rate);
    ost.set_parameters(input_stream.parameters());

    octx.write_header()?;

    // 初始化格式转换器(这里保持原视频格式输出)
    let mut scaler = Context::get(
        decoder.format(),
        decoder.width(),
        decoder.height(),
        decoder.format(),
        decoder.width(),
        decoder.height(),
        Flags::BILINEAR,
    )?;

    let mut decoded = frame::Video::empty();
    let mut encoded = frame::Video::empty();
    let mut packet = ffmpeg::Packet::empty();

    let mut frame_count = 0;

    // 读取并处理帧,直到达到指定时长
    while frame_count < total_frames && ictx.read_frame(&mut packet).is_ok() {
        if packet.stream_index() != stream_index {
            continue;
        }

        // 解码帧
        if decoder.send_packet(&packet).is_ok() {
            while decoder.receive_frame(&mut decoded).is_ok() {
                scaler.run(&decoded, &mut encoded)?;
                // 调整帧时间戳,以起始时间为零点
                encoded.set_pts(Some(decoded.pts().unwrap() - start_ts));

                // 编码并写入输出
                let mut encode_packet = ffmpeg::Packet::empty();
                if ost.codec().encoder().send_frame(&encoded).is_ok() {
                    while ost.codec().encoder().receive_packet(&mut encode_packet).is_ok() {
                        encode_packet.set_stream_index(ost.index());
                        octx.write_frame(&encode_packet)?;
                    }
                }

                frame_count += 1;
                if frame_count >= total_frames {
                    break;
                }
            }
        }
        packet.unref();
    }

    // 写入文件尾,完成输出
    ost.codec().encoder().send_eof()?;
    while ost.codec().encoder().receive_packet(&mut packet).is_ok() {
        packet.set_stream_index(ost.index());
        octx.write_frame(&packet)?;
    }
    octx.write_trailer()?;

    Ok(())
}

fn main() {
    // 示例:裁剪input.mp4中从10秒开始的5秒内容,输出到output.mp4
    if let Err(e) = crop_video("input.mp4", "output.mp4", 10.0, 5.0) {
        eprintln!("裁剪失败: {}", e);
    } else {
        println!("裁剪完成");
    }
}

3. 关键逻辑说明

  • 起始时间定位:通过ictx.seek(start_ts, stream_index)将输入流定位到指定时间戳,时间戳需要转换为视频流的时间基单位
  • 时长控制:通过计算目标时长对应的总帧数,循环处理直到达到帧数量上限
  • 静态编译:依赖中的static特性确保所有FFmpeg依赖被静态链接到二进制文件中,编译后可直接在同架构的系统上运行

4. 编译注意事项

  • Linux系统:需先安装编译依赖:sudo apt install build-essential yasm libx264-dev
  • macOS系统:可通过Homebrew安装依赖:brew install yasm x264
  • Windows系统:建议使用MSYS2环境,安装对应编译工具链和依赖

内容的提问来源于stack exchange,提问作者Michael Savchenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:25:24