1.日志系统
常用的日志级别:
- AV_LOG_ERROR
- AV_LOG_WARNING
- AV_LOG_INFO
- AV_LOG_DEBUG
#include #include int main(int argc, char *argv[]) { av_log_set_level(AV_LOG_DEBUG); av_log(NULL, AV_LOG_DEBUG, "hello world!\n"); return 0; }
2.文件的删除与重命名
文件删除与重命名的API:
- avpriv_io_delete()
- avpriv_io_move()
int ret; // 重命名 ret = avpriv_io_move("111.txt", "222.txt"); if(ret
3.目录操作
操作目录重要函数:
- avio_open_dir()
- avio_read_dir()
- avio_close_dir()
操作目录重要结构体:
- AVIODirContext
- AVIODirEntry
avdevice_register_all(); int ret; AVIODirContext *ctx = NULL; AVIODirEntry *entry = NULL; av_log_set_level(AV_LOG_INFO); ret = avio_open_dir(&ctx, "./", NULL); if(ret size, entry->name); avio_free_directory_entry(&entry); } __fail: avio_close_dir(&ctx);
4.抽取音频数据
- 1.处理一些参数
- 2.打开多媒体文件
- 3.从多媒体文件中找到音频流
- 4.打开目的文件的上下文
- 5.为目的文件,创建一个新的音频流
- 6.设置输出音频参数
- 7.写多媒体文件头到目的文件
- 8…从源多媒体文件中读音频数据到目的文件中
- 9.写多媒体文件尾到文件中
- 10.将申请的资源释放掉
步骤比较多,一点一点来实现:
// 1.处理一些参数 if(argc
// 3.从多媒体文件中找到音频流 idx = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0); if(idx oformat = outFmt; // 5.为目的文件,创建一个新的音频流 outStream = av_format_new_stream(oFmtCtx, NULL); // 6.设置输出音频参数 inStream = pFmtCtx->stream[idx]; avcodec_parameters_copy(outStream->codecpar, inStream->codecpar); outStream->codecpar->codec_tag = 0;
// 7.写多媒体文件头到目的文件 ret = avformat_write_header(oFmtCtx, NULL); if(ret = 0) { if(pkt.stream_index == idx) { pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); pkt.dts = pkt.dts; 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; }
6.抽取视频数据
与处理音频流程相同,简单修改即可
// 3.从多媒体文件中找到视频流 idx = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if(idx = 0) { if(pkt.stream_index == idx) { pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); pkt.dts = av_rescale_q_rnd(pkt.dts, inStream->time_base, outStream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); // pkt.dts = pkt.dts; 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); } }
6.多媒体格式转封装
7.视频裁剪
程序是在上面的程序基础上修改的,这里就把核心修改地方贴出来。
有两个注意点:(对应下面的修改2和修改3)
第一个是音视频时间的问题。
针对音频:从第5秒钟截取,那他就是第5秒。针对视频:因为有IPB 帧,如果刚好第5秒是P帧或者B帧,没有了I帧,那么就不能解码成功,播放的时候就会花屏。
解决:告诉ffmpeg如果不是I帧,就要向前或者向后找最近的I帧
第二个是时间的问题。
由于是裁剪,所以需要计算相对时间。 使用后面的时间减去第一个时间基的时间,这样子才能保证时间的正确性。音频的dts和pts是相同的,而视频可能是不同的,所以这里需要多加一步判断。
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。
还没有评论,来说两句吧...