常用日志级别(由高到低排序)
AV_LOG_ERROR
AV_LOG_WARNING
AV_LOG_INFO
AV_LOG_DEBUG
// ffmpeg_log.cpp
extern "C" {
#include
}
#pragma comment(lib,"avutil.lib")
int main(int argc, char *argv[])
{
av_log_set_level(AV_LOG_DEBUG);
// 除去前面两个参数,av_log跟C语言printf差不多
av_log(NULL, AV_LOG_DEBUG, "hello world!%s\n", "123");
return 0;
}
extern "C" {
#include
#include
}
int main(int argc, char** argv)
{
int ret = 0;
// 重命名
ret = avpriv_io_move("./1.txt", "2.txt");
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "Failed to rename\n");
return -1;
}
av_log(NULL, AV_LOG_INFO, "Rename successfully.\n");
// 删除文件
ret = avpriv_io_delete("./3.txt");
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "Failed to delete.\n");
return -1;
}
av_log(NULL, AV_LOG_INFO, "Delete successfully.\n");
return 0;
}
#include
using namespace std;
extern "C" {
#include
#include
#include
}
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avformat.lib")
int main(int argc, char* argv[]) {
int ret = -1;
int idx = -1;
//1. 处理一些参数;将1.mp4中的音频提取出来保存为1.acc
char src[] = "1.mp4";
char dst[] = "1.aac";
AVFormatContext* pFmtCtx = NULL;
AVFormatContext* oFmtCtx = NULL;
AVOutputFormat* outFmt = NULL;
AVStream* outStream = NULL;
AVStream* inStream = NULL;
AVPacket pkt;
//2. 打开多媒体文件
if ((ret = avformat_open_input(&pFmtCtx, src, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "打开多媒体文件错误\n");
exit(-1);
}
//3. 从多媒体文件中找到音频流
idx = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
if (idx < 0) {
av_log(pFmtCtx, AV_LOG_ERROR, "Does not include audio stream!\n");
goto _ERROR;
}
//4. 打开目的文件的上下文
oFmtCtx = avformat_alloc_context();
if (!oFmtCtx) {
av_log(NULL, AV_LOG_ERROR, "NO Memory!\n");
goto _ERROR;
}
outFmt = av_guess_format(NULL, dst, NULL);
oFmtCtx->oformat = outFmt;
//5. 为目的文件,创建一个新的音频流
outStream = avformat_new_stream(oFmtCtx, NULL);
//6. 设置输出音频参数
inStream = pFmtCtx->streams[idx];
avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
outStream->codecpar->codec_tag = 0;
//绑定
ret = avio_open2(&oFmtCtx->pb, dst, AVIO_FLAG_WRITE, NULL, NULL);
if (ret < 0) {
av_log(oFmtCtx, AV_LOG_ERROR, "绑定失败");
goto _ERROR;
}
//7. 写多媒体文件头到目的文件
ret = avformat_write_header(oFmtCtx, NULL);
if (ret < 0) {
cout << "写多媒体文件头到目的文件错误" << endl;
av_log(oFmtCtx, AV_LOG_ERROR, "写多媒体文件头到目的文件错误");
goto _ERROR;
}
//8. 从源多媒体文件中读到音频数据到目的文件中
while (av_read_frame(pFmtCtx, &pkt) >= 0) {
if (pkt.stream_index == idx) {
pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.dts = pkt.pts;
pkt.duration = av_rescale_q(pkt.duration, inStream->time_base, outStream->time_base);
pkt.stream_index = 0;
pkt.pos = -1;
av_interleaved_write_frame(oFmtCtx, &pkt);
av_packet_unref(&pkt);
}
}
//9. 写多媒体文件尾到文件中
av_write_trailer(oFmtCtx);
//10. 将申请的资源释放掉
_ERROR:
if (pFmtCtx) {
avformat_close_input(&pFmtCtx);
pFmtCtx = NULL;
}
if (oFmtCtx->pb) {
avio_close(oFmtCtx->pb);
}
if (oFmtCtx) {
avformat_free_context(oFmtCtx);
oFmtCtx = NULL;
}
cout << "提取音频数据成功" << endl;
return 0;
}
#include
using namespace std;
extern "C" {
#include
#include
#include
}
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avformat.lib")
int main(int argc, char* argv[]) {
int ret = -1;
int idx = -1;
//1. 处理一些参数;抽取1.mp4中的视频保存到2.mp4
char src[] = "1.mp4";
char dst[] = "2.mp4";
AVFormatContext* pFmtCtx = NULL;
AVFormatContext* oFmtCtx = NULL;
AVOutputFormat* outFmt = NULL;
AVStream* outStream = NULL;
AVStream* inStream = NULL;
AVPacket pkt;
av_log_set_level(AV_LOG_DEBUG);
//2. 打开多媒体文件
if ((ret = avformat_open_input(&pFmtCtx, src, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "打开多媒体文件失败\n");
exit(-1);
}
//3. 从多媒体文件中找到视频流
idx = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (idx < 0) {
av_log(pFmtCtx, AV_LOG_ERROR, "Does not include audio stream!\n");
goto _ERROR;
}
//4. 打开目的文件的上下文
oFmtCtx = avformat_alloc_context();
if (!oFmtCtx) {
av_log(NULL, AV_LOG_ERROR, "NO Memory!\n");
goto _ERROR;
}
outFmt = av_guess_format(NULL, dst, NULL);
oFmtCtx->oformat = outFmt;
//5. 为目的文件,创建一个新的视频流
outStream = avformat_new_stream(oFmtCtx, NULL);
//6. 设置输出视频参数
inStream = pFmtCtx->streams[idx];
avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
outStream->codecpar->codec_tag = 0;
//绑定
ret = avio_open2(&oFmtCtx->pb, dst, AVIO_FLAG_WRITE, NULL, NULL);
if (ret < 0) {
av_log(oFmtCtx, AV_LOG_ERROR, "绑定失败");
goto _ERROR;
}
//7. 写多媒体文件头到目的文件
ret = avformat_write_header(oFmtCtx, NULL);
if (ret < 0) {
av_log(oFmtCtx, AV_LOG_ERROR, "写多媒体文件头到目的文件失败");
goto _ERROR;
}
//8. 从源多媒体文件中读到视频数据到目的文件中
while (av_read_frame(pFmtCtx, &pkt) >= 0) {
if (pkt.stream_index == idx) {
pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.dts = av_rescale_q_rnd(pkt.dts, inStream->time_base, outStream->time_base, (enum AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
pkt.duration = av_rescale_q(pkt.duration, inStream->time_base, outStream->time_base);
pkt.stream_index = 0;
pkt.pos = -1;
av_interleaved_write_frame(oFmtCtx, &pkt);
av_packet_unref(&pkt);
}
}
//9. 写多媒体文件尾到文件中
av_write_trailer(oFmtCtx);
//10. 将申请的资源释放掉
_ERROR:
if (pFmtCtx) {
avformat_close_input(&pFmtCtx);
pFmtCtx = NULL;
}
if (oFmtCtx->pb) {
avio_close(oFmtCtx->pb);
}
if (oFmtCtx) {
avformat_free_context(oFmtCtx);
oFmtCtx = NULL;
}
cout << "抽取视频数据成功" << endl;
return 0;
}
#include
using namespace std;
extern "C" {
#include
#include
#include
}
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avformat.lib")
int main(int argc, char* argv[]) {
int ret = -1;
int idx = -1;
int stream_idx = 0;
int i = 0;
//1. 处理一些参数;
char src[] = "1.mp4";
char dst[] = "1.wmv";
int* stream_map = NULL;
AVFormatContext* pFmtCtx = NULL;
AVFormatContext* oFmtCtx = NULL;
const AVOutputFormat* outFmt = NULL;
AVPacket pkt;
av_log_set_level(AV_LOG_DEBUG);
//2. 打开多媒体文件
if ((ret = avformat_open_input(&pFmtCtx, src, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "error");
return -1;
}
//4. 打开目的文件的上下文
avformat_alloc_output_context2(&oFmtCtx, NULL, NULL, dst);
if (!oFmtCtx) {
av_log(NULL, AV_LOG_ERROR, "NO MEMORY!\n");
goto _ERROR;
}
stream_map = (int *)av_calloc(pFmtCtx->nb_streams, sizeof(int));
if (!stream_map) {
av_log(NULL, AV_LOG_ERROR, "NO MEMORY!\n");
goto _ERROR;
}
for (i = 0; i < pFmtCtx->nb_streams; i++) {
AVStream* outStream = NULL;
AVStream* inStream = pFmtCtx->streams[i];
AVCodecParameters* inCodecPar = inStream->codecpar;
if (inCodecPar->codec_type != AVMEDIA_TYPE_AUDIO &&
inCodecPar->codec_type != AVMEDIA_TYPE_VIDEO &&
inCodecPar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
stream_map[i] = -1;
continue;
}
stream_map[i] = stream_idx++;
//5. 为目的文件,创建一个新的视频流
outStream = avformat_new_stream(oFmtCtx, NULL);
if (!outStream) {
av_log(oFmtCtx, AV_LOG_ERROR, "NO MEMORY!\n");
goto _ERROR;
}
avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
outStream->codecpar->codec_tag = 0;
}
//绑定
ret = avio_open2(&oFmtCtx->pb, dst, AVIO_FLAG_WRITE, NULL, NULL);
if (ret < 0) {
av_log(oFmtCtx, AV_LOG_ERROR, "绑定失败");
goto _ERROR;
}
//7. 写多媒体文件头到目的文件
ret = avformat_write_header(oFmtCtx, NULL);
if (ret < 0) {
av_log(oFmtCtx, AV_LOG_ERROR, "写多媒体文件头到目的文件失败");
goto _ERROR;
}
//8. 从源多媒体文件中读取音频/视频/字幕数据到目的文件中
while (av_read_frame(pFmtCtx, &pkt) >= 0) {
AVStream* inStream, * outStream;
inStream = pFmtCtx->streams[pkt.stream_index];
if (stream_map[pkt.stream_index] < 0) {
av_packet_unref(&pkt);
continue;
}
pkt.stream_index = stream_map[pkt.stream_index];
outStream = oFmtCtx->streams[pkt.stream_index];
av_packet_rescale_ts(&pkt, inStream->time_base, outStream->time_base);
pkt.pos = -1;
av_interleaved_write_frame(oFmtCtx, &pkt);
av_packet_unref(&pkt);
}
//9. 写多媒体文件尾到文件中
av_write_trailer(oFmtCtx);
//10. 将申请的资源释放掉
_ERROR:
if (pFmtCtx) {
avformat_close_input(&pFmtCtx);
pFmtCtx = NULL;
}
if (oFmtCtx->pb) {
avio_close(oFmtCtx->pb);
}
if (oFmtCtx) {
avformat_free_context(oFmtCtx);
oFmtCtx = NULL;
}
if (stream_map) {
av_free(stream_map);
}
return 0;
}
#include
using namespace std;
extern "C" {
#include
#include
#include
#include
}
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avformat.lib")
static void log_packet(AVFormatContext* fmtCtx, const AVPacket* pkt, int64_t pts_start, int64_t dts_start) {
// = &fmtCtx->streams[pkt->stream_index]->time_base;
av_log(fmtCtx,
AV_LOG_INFO,
"pts:%s dts:%s pts_diff:%lld dts_diff:%lld stream_idx:%d pts_start:%lld dts_start:%lld\n",
av_ts2str(pkt->pts),
av_ts2str(pkt->dts),
pkt->pts - pts_start,
pkt->dts - dts_start,
pkt->stream_index,
pts_start,
dts_start);
}
int main(int argc, char* argv[]) {
int ret = -1;
int idx = -1;
int stream_idx = 0;
int i = 0;
//1. 处理一些参数;从视频的30秒裁剪到视频的50秒
char src[] = "1.mp4";
char dst[] = "cut.mp4";
double starttime = 30;
double endtime = 50;
int* stream_map = NULL;
int64_t* dts_start_time = NULL;
int64_t* pts_start_time = NULL;
AVFormatContext* pFmtCtx = NULL;
AVFormatContext* oFmtCtx = NULL;
const AVOutputFormat* outFmt = NULL;
AVPacket pkt;
av_log_set_level(AV_LOG_DEBUG);
//2. 打开多媒体文件
if ((ret = avformat_open_input(&pFmtCtx, src, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "%s\n", av_err2str(ret));
exit(-1);
}
//4. 打开目的文件的上下文
avformat_alloc_output_context2(&oFmtCtx, NULL, NULL, dst);
if (!oFmtCtx) {
av_log(NULL, AV_LOG_ERROR, "NO MEMORY!\n");
goto _ERROR;
}
stream_map = (int *)av_calloc(pFmtCtx->nb_streams, sizeof(int));
if (!stream_map) {
av_log(NULL, AV_LOG_ERROR, "NO MEMORY!\n");
goto _ERROR;
}
for (i = 0; i < pFmtCtx->nb_streams; i++) {
AVStream* outStream = NULL;
AVStream* inStream = pFmtCtx->streams[i];
AVCodecParameters* inCodecPar = inStream->codecpar;
if (inCodecPar->codec_type != AVMEDIA_TYPE_AUDIO &&
inCodecPar->codec_type != AVMEDIA_TYPE_VIDEO &&
inCodecPar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
stream_map[i] = -1;
continue;
}
stream_map[i] = stream_idx++;
//5. 为目的文件,创建一个新的视频流
outStream = avformat_new_stream(oFmtCtx, NULL);
if (!outStream) {
av_log(oFmtCtx, AV_LOG_ERROR, "NO MEMORY!\n");
goto _ERROR;
}
avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
outStream->codecpar->codec_tag = 0;
}
//绑定
ret = avio_open2(&oFmtCtx->pb, dst, AVIO_FLAG_WRITE, NULL, NULL);
if (ret < 0) {
av_log(oFmtCtx, AV_LOG_ERROR, "绑定失败");
goto _ERROR;
}
//7. 写多媒体文件头到目的文件
ret = avformat_write_header(oFmtCtx, NULL);
if (ret < 0) {
av_log(oFmtCtx, AV_LOG_ERROR, "写多媒体文件头到目的文件失败");
goto _ERROR;
}
//seek
ret = av_seek_frame(pFmtCtx, -1, starttime * AV_TIME_BASE, AVSEEK_FLAG_BACKWARD);
if (ret < 0) {
av_log(oFmtCtx, AV_LOG_ERROR, "seek error");
goto _ERROR;
}
dts_start_time = (int64_t * )av_calloc(pFmtCtx->nb_streams, sizeof(int64_t));
for (int t = 0; t < pFmtCtx->nb_streams; t++) {
dts_start_time[t] = -1;
}
pts_start_time = (int64_t * )av_calloc(pFmtCtx->nb_streams, sizeof(int64_t));
for (int t = 0; t < pFmtCtx->nb_streams; t++) {
pts_start_time[t] = -1;
}
//8. 从源多媒体文件中读取音频/视频/字幕数据到目的文件中
while (av_read_frame(pFmtCtx, &pkt) >= 0) {
AVStream* inStream, * outStream;
if (dts_start_time[pkt.stream_index] == -1 && pkt.dts >= 0) {
dts_start_time[pkt.stream_index] = pkt.dts;
}
if (pts_start_time[pkt.stream_index] == -1 && pkt.pts >= 0) {
pts_start_time[pkt.stream_index] = pkt.pts;
}
inStream = pFmtCtx->streams[pkt.stream_index];
if (av_q2d(inStream->time_base) * pkt.pts > endtime) {
av_log(oFmtCtx, AV_LOG_INFO, "success!\n");
break;
}
if (stream_map[pkt.stream_index] < 0) {
av_packet_unref(&pkt);
continue;
}
//printf("pkt.pts=%lld, pkt.dts=%lld\n", pkt.pts, pkt.dts);
log_packet(pFmtCtx, &pkt, pts_start_time[pkt.stream_index], dts_start_time[pkt.stream_index]);
pkt.pts = pkt.pts - pts_start_time[pkt.stream_index];
pkt.dts = pkt.dts - dts_start_time[pkt.stream_index];
if (pkt.dts > pkt.pts) {
pkt.pts = pkt.dts;
}
pkt.stream_index = stream_map[pkt.stream_index];
outStream = oFmtCtx->streams[pkt.stream_index];
av_packet_rescale_ts(&pkt, inStream->time_base, outStream->time_base);
pkt.pos = -1;
av_interleaved_write_frame(oFmtCtx, &pkt);
av_packet_unref(&pkt);
}
//9. 写多媒体文件尾到文件中
av_write_trailer(oFmtCtx);
//10. 将申请的资源释放掉
_ERROR:
if (pFmtCtx) {
avformat_close_input(&pFmtCtx);
pFmtCtx = NULL;
}
if (oFmtCtx->pb) {
avio_close(oFmtCtx->pb);
}
if (oFmtCtx) {
avformat_free_context(oFmtCtx);
oFmtCtx = NULL;
}
if (stream_map) {
av_free(stream_map);
}
if (dts_start_time) {
av_free(dts_start_time);
}
if (pts_start_time) {
av_free(pts_start_time);
}
cout << "裁剪成功" << endl;
return 0;
}