21xrx.com
2025-04-14 18:43:52 Monday
文章检索 我的文章 写文章
FFmpeg API在Linux下的视频处理
2023-11-20 18:58:28 深夜i     14     0
FFmpeg API Linux 视频处理

FFmpeg是一个开源的音视频处理工具,可以在各种平台上使用。它提供了丰富的API,可以用来处理视频文件,包括裁剪、转码、合并等操作。在Linux操作系统下,FFmpeg API可以非常方便地用于视频处理。

首先,要在Linux系统中使用FFmpeg API,需要先安装FFmpeg库。可以通过命令行工具来安装,例如在Ubuntu系统中可以运行"sudo apt get install ffmpeg"来进行安装。安装完成后,就可以在代码中引入FFmpeg库并使用其中的API了。

在视频处理中,常用的操作之一是裁剪视频。通过FFmpeg API,可以非常简单地实现视频的裁剪功能。只需要设置裁剪的起始时间和结束时间,以及输出文件名和格式,就可以完成裁剪操作。例如,以下代码可以将一个视频片段从10秒到20秒的部分进行裁剪:

AVFormatContext *inputFormatCtx = NULL;
AVFormatContext *outputFormatCtx = NULL;
AVCodecContext *inputCodecCtx = NULL;
AVCodecContext *outputCodecCtx = NULL;
AVPacket packet;
av_register_all();
if (avformat_open_input(&inputFormatCtx, "input.mp4", NULL, NULL) != 0)
  return -1;
if (avformat_find_stream_info(inputFormatCtx, NULL) < 0)
  return -1;
avformat_alloc_output_context2(&outputFormatCtx, NULL, NULL, "output.mp4");
if (!outputFormatCtx)
  return -1;
for (int i = 0; i < inputFormatCtx->nb_streams; i++) {
  AVStream *inStream = inputFormatCtx->streams[i];
  AVStream *outStream = avformat_new_stream(outputFormatCtx, inStream->codec->codec);
  if (!outStream)
    return -1;
  
  inputCodecCtx = inStream->codec;
  outputCodecCtx = outStream->codec;
  if (avcodec_copy_context(outputCodecCtx, inputCodecCtx) != 0)
    return -1;
  
  outputCodecCtx->time_base = inputCodecCtx->time_base;
  outputCodecCtx->start_time = inputCodecCtx->start_time;
  outputCodecCtx->duration = inputCodecCtx->duration;
  outputCodecCtx->bit_rate = 0;
}
if (avio_open(&outputFormatCtx->pb, "output.mp4", AVIO_FLAG_WRITE) < 0)
  return -1;
if (avformat_write_header(outputFormatCtx, NULL) < 0)
  return -1;
int64_t startTime = 10 * AV_TIME_BASE;
int64_t endTime = 20 * AV_TIME_BASE;
int64_t duration = endTime - startTime;
while (av_read_frame(inputFormatCtx, &packet) >= 0) {
  AVStream *inStream = inputFormatCtx->streams[packet.stream_index];
  AVStream *outStream = outputFormatCtx->streams[packet.stream_index];
  packet.pts = av_rescale_q_rnd(packet.pts, inStream->time_base, outStream->time_base, AV_ROUND_NEAR_INF);
  packet.dts = av_rescale_q_rnd(packet.dts, inStream->time_base, outStream->time_base, AV_ROUND_NEAR_INF);
  packet.duration = av_rescale_q(packet.duration, inStream->time_base, outStream->time_base);
  packet.pos = -1;
  if (packet.pts >= startTime && packet.pts <= endTime) {
    if (av_interleaved_write_frame(outputFormatCtx, &packet) < 0)
      return -1;
    
  }
  av_packet_unref(&packet);
  if (packet.pts > endTime)
    break;
  
}
av_write_trailer(outputFormatCtx);
avformat_close_input(&inputFormatCtx);
avformat_free_context(outputFormatCtx);

此外,FFmpeg API还可以用于视频的转码。转码是将一个视频文件的编码格式转换为另一种编码格式,可以实现不同设备的兼容性。通过FFmpeg API,可以非常方便地实现视频的转码操作。只需要指定输入文件名、输入文件的编码格式,以及输出文件名和输出文件的编码格式,就可以完成转码操作。以下是一个简单的转码示例:

AVFormatContext *inputFormatCtx = NULL;
AVFormatContext *outputFormatCtx = NULL;
AVCodecContext *inputCodecCtx = NULL;
AVCodecContext *outputCodecCtx = NULL;
AVPacket packet;
av_register_all();
if (avformat_open_input(&inputFormatCtx, "input.mp4", NULL, NULL) != 0)
  return -1;
if (avformat_find_stream_info(inputFormatCtx, NULL) < 0)
  return -1;
avformat_alloc_output_context2(&outputFormatCtx, NULL, NULL, "output.mp4");
if (!outputFormatCtx)
  return -1;
for (int i = 0; i < inputFormatCtx->nb_streams; i++) {
  AVStream *inStream = inputFormatCtx->streams[i];
  AVStream *outStream = avformat_new_stream(outputFormatCtx, inStream->codec->codec);
  if (!outStream)
    return -1;
  
  inputCodecCtx = inStream->codec;
  outputCodecCtx = outStream->codec;
  AVCodec *codec = avcodec_find_decoder(inputCodecCtx->codec_id);
  if (!codec)
    return -1;
  
  if (avcodec_open2(inputCodecCtx, codec, NULL) < 0)
    return -1;
  
  AVCodec *outputCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
  if (!outputCodec)
    return -1;
  
  outputCodecCtx = avcodec_alloc_context3(outputCodec);
  if (!outputCodecCtx)
    return -1;
  
  outputCodecCtx->width = inputCodecCtx->width;
  outputCodecCtx->height = inputCodecCtx->height;
  outputCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
  outputCodecCtx->bit_rate = inputCodecCtx->bit_rate;
  if (avcodec_open2(outputCodecCtx, outputCodec, NULL) < 0)
    return -1;
  
  avcodec_close(inputCodecCtx);
  inputCodecCtx = NULL;
}
if (avio_open(&outputFormatCtx->pb, "output.mp4", AVIO_FLAG_WRITE) < 0)
  return -1;
if (avformat_write_header(outputFormatCtx, NULL) < 0)
  return -1;
while (av_read_frame(inputFormatCtx, &packet) >= 0) {
  AVStream *inStream = inputFormatCtx->streams[packet.stream_index];
  AVStream *outStream = outputFormatCtx->streams[packet.stream_index];
  av_packet_rescale_ts(&packet, inStream->time_base, outStream->time_base);
  packet.pos = -1;
  if (av_interleaved_write_frame(outputFormatCtx, &packet) < 0)
    return -1;
  
  av_packet_unref(&packet);
}
av_write_trailer(outputFormatCtx);
avformat_close_input(&inputFormatCtx);
avformat_free_context(outputFormatCtx);

上述代码将一个输入文件进行转码,将其输出为H.264编码的MP4文件。此代码还包括了将输入文件的音视频流解码和编码的过程,以及将解码后的编码数据写入输出文件的过程。

总结起来,FFmpeg API在Linux下的视频处理非常实用。通过这些API,可以实现视频的裁剪、转码等功能,为视频处理提供了很大的便利。无论是对于独立开发者还是企业用户,FFmpeg API都是非常有价值的工具,可以满足各种视频处理需求。

  
  

评论区

请求出错了