📅  最后修改于: 2023-12-03 15:30:45.346000             🧑  作者: Mango
FFMPEG是一个免费的开源跨平台音视频处理工具,它可以处理各种各样的音频或视频文件。在本文中,我们将介绍如何使用FFMPEG结合音频和视频。
FFMPEG可以在Windows、Linux和Mac OS X等多平台运行。安装步骤如下:
在终端中输入以下命令:
sudo apt-get install ffmpeg
在终端中输入以下命令:
brew install ffmpeg
使用FFMPEG结合音频和视频有以下两种方式:
在命令行中输入以下命令:
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a copy output.mp4
这将从“video.mp4”和“audio.mp3”中提取视频和音频流并将它们结合在一起。最后的文件名为“output.mp4”(你可以将其替换为你想要的任何文件名),该文件将包含合并的音频和视频流。
如果你在使用FFMPEG的应用程序中结合音频和视频,你可以使用FFMPEG库。以下是一个用C ++示例:
#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
}
int main()
{
const char* videoFilePath = "video.mp4";
const char* audioFilePath = "audio.mp3";
const char* outputFilePath = "output.mp4";
std::string error;
av_register_all();
AVFormatContext* videoFormatCtx = NULL;
if (avformat_open_input(&videoFormatCtx, videoFilePath, NULL, NULL) != 0)
{
error = "Could not open video input file";
goto bail;
}
if (avformat_find_stream_info(videoFormatCtx, NULL) < 0)
{
error = "Could not find video stream info";
goto bail;
}
int videoStreamIndex = -1;
AVStream* videoStream = NULL;
for (unsigned int i = 0; i < videoFormatCtx->nb_streams; i++)
{
auto stream = videoFormatCtx->streams[i];
if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStreamIndex = i;
videoStream = stream;
break;
}
}
if (videoStreamIndex == -1 || videoStream == NULL)
{
error = "Could not find video stream";
goto bail;
}
AVFormatContext* audioFormatCtx = NULL;
if (avformat_open_input(&audioFormatCtx, audioFilePath, NULL, NULL) != 0)
{
error = "Could not open audio input file";
goto bail;
}
if (avformat_find_stream_info(audioFormatCtx, NULL) < 0)
{
error = "Could not find audio stream info";
goto bail;
}
int audioStreamIndex = -1;
AVStream* audioStream = NULL;
for (unsigned int i = 0; i < audioFormatCtx->nb_streams; i++)
{
auto stream = audioFormatCtx->streams[i];
if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
{
audioStreamIndex = i;
audioStream = stream;
break;
}
}
if (audioStreamIndex == -1 || audioStream == NULL)
{
error = "Could not find audio stream";
goto bail;
}
AVFormatContext* outputFormatCtx = NULL;
int outputWidth = videoStream->codecpar->width;
int outputHeight = videoStream->codecpar->height;
AVRational outputTimeBase = videoStream->time_base;
std::remove(outputFilePath);
if (avformat_alloc_output_context2(&outputFormatCtx, NULL, NULL, outputFilePath) < 0)
{
error = "Could not allocate output format context";
goto bail;
}
AVOutputFormat* outputFormat = outputFormatCtx->oformat;
AVCodecContext* videoCodecCtx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(videoCodecCtx, videoStream->codecpar);
videoCodecCtx->codec_tag = 0;
videoCodecCtx->codec_id = outputFormat->video_codec;
videoCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
videoCodecCtx->bit_rate = videoStream->codecpar->bit_rate;
videoCodecCtx->width = outputWidth;
videoCodecCtx->height = outputHeight;
videoCodecCtx->time_base = outputTimeBase;
AVCodecContext* audioCodecCtx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(audioCodecCtx, audioStream->codecpar);
audioCodecCtx->codec_tag = 0;
audioCodecCtx->codec_id = outputFormat->audio_codec;
audioCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
if (avformat_new_stream(outputFormatCtx, NULL) == NULL)
{
error = "Could not create output stream";
goto bail;
}
AVStream* outputStream = outputFormatCtx->streams[0];
if (avcodec_parameters_from_context(outputStream->codecpar, videoCodecCtx) < 0)
{
error = "Could not set stream parameters for video codec";
goto bail;
}
if (avcodec_parameters_from_context(outputStream->codecpar, audioCodecCtx) < 0)
{
error = "Could not set stream parameters for audio codec";
goto bail;
}
if (avio_open2(&outputFormatCtx->pb, outputFilePath, AVIO_FLAG_WRITE, NULL, NULL) < 0)
{
error = "Could not open output file";
goto bail;
}
if (avformat_write_header(outputFormatCtx, NULL) < 0)
{
error = "Could not write output file header";
goto bail;
}
AVPacket pkt;
while (true)
{
if (av_read_frame(videoFormatCtx, &pkt) < 0)
{
break;
}
if (pkt.stream_index == videoStreamIndex)
{
av_packet_rescale_ts(&pkt, videoStream->time_base, outputTimeBase);
if (av_interleaved_write_frame(outputFormatCtx, &pkt) < 0)
{
error = "Could not write video frame to output file";
goto bail;
}
}
av_packet_unref(&pkt);
}
while (true)
{
if (av_read_frame(audioFormatCtx, &pkt) < 0)
{
break;
}
if (pkt.stream_index == audioStreamIndex)
{
av_packet_rescale_ts(&pkt, audioStream->time_base, outputTimeBase);
if (av_interleaved_write_frame(outputFormatCtx, &pkt) < 0)
{
error = "Could not write audio frame to output file";
goto bail;
}
}
av_packet_unref(&pkt);
}
if (av_write_trailer(outputFormatCtx) < 0)
{
error = "Could not write output file trailer";
}
bail:
if (!error.empty())
{
std::cerr << error << std::endl;
return -1;
}
return 0;
}
这个程序将从“video.mp4”和“audio.mp3”中提取视频和音频流并将它们结合在一起。最后的文件名为“output.mp4”(你可以将其替换为你想要的任何文件名),该文件将包含合并的音频和视频流。
FFMPEG是一个功能强大的音视频处理工具,它支持各种各样的格式,可以应用于多种场景。本文介绍了如何使用FFMPEG结合音频和视频以及如何安装FFMPEG。如果你对FFMPEG感兴趣,你可以深入研究相关的文档、教程和示例程序。