iOS音视频—FFmepg基础知识:命令行工具使用&封装格式&视频编码音频编码数据了解&视频像素音频采样数据格式

iOS音视频相关目录


FFmepg基础知识

封装格式

1、封装格式:mp4、mov、flv、wmv等等…
2、作用:视频流+音频流按照格式进行存储在一个文件中
3、MPEG2-TS格式:传输流,又称TS、TP、MPEG-TS或M2T,用于音效、图像与数据的通信协议。属于视频压缩数据格式,特点:数据排版,不包含头文件,数据大小固定(188byte)的TS-Packet.

在这里插入图片描述

4、FLV格式:FLASH VIDEO简称

  • 特点是:文件极小,加载速度极快,使得网络观看视频文件成为可能,有效解决了视频文件导入Flash后,使导出的SWF文件体积庞大不能在网络上很好的使用等问题。
  • 文件结构:FLV是一个二进制文件,由文件头和很多tag组成,tag又可以分为三类:audio,video,script,分别代表音频流,视频流,脚本流。
    FLV文件=FLV头文件+tag1+tag内容1+tag2+tag内容2+…+…+tagN+tag内容N。
  • FLV头文件:(9字节)
    1-3: 前3个字节是文件格式标识(FLV 0x46 0x4C 0x56).
    4-4: 第4个字节是版本(0x01)
    5-5: 第5个字节的前5个bit是保留的必须是0.
    6-9: 第6-9的四个字节还是保留的.其数据为 00000009 .
    整个文件头的长度,一般是9(3+1+1+4)

视频编码数据了解

1、视频编码的作用:将视频像素数据(YUV、RGB)进行压缩,压缩成为视频码流,从而降低视频数据量(减小内存的占用)。
2、视频编码格式有哪些:

在这里插入图片描述

3、H.264视频压缩数据格式:算法复杂->占用内存少 (例如:帧间预测、帧内预测…)->提高压缩性能

音频编码数据了解

1、音频编码作用:将音频采样数据(YUV、RGB)进行压缩,压缩成为音频码流,从而降低音频数据量(减小内存的占用)。
2、音频编码格式有哪些:
在这里插入图片描述
3、AAC格式:高级音频编码,基于MPEG-2的音频编码技术。

优点:相对于mp3,AAC格式的音质更佳,文件更小。
不足:AAC属于有损压缩的格式,与时下流行的APE、FLAC等无损格式相比音质存在“本质上”的差距。加之,传输速度更快的USB3.0和16G以上大容量MP3正在加速普及,也使得AAC头上“小巧”的光环不复存在
特点:
①提升的压缩率:可以以更小的文件大小获得更高的音质;
②支持多声道:可提供最多48个全音域声道;
③更高的解析度:最高支持96KHz的采样频率;
④提升的解码效率:解码播放所占的资源更少;

视频像素数据格式

1、作用:保存了屏幕上面每一个像素点的值
2、视频像素数据格式种类:常见格式包含:RGB24、RGB32、YUV420P、YUV422P、YUV444P等,一般最常见:YUV420P
3、视频像素文件大小计算
例如:RGB24高清视频体积(1个小时时长)
体积:3600 (秒) * 25 (帧率)* 1920 * 1080 (屏幕大小) * 3(3字节 = 8位 * 3(RGB)=24位) = 559GB(非常大)
假设:帧率为25HZ,采样精度8bit,3字节
4、YUV播放器:注意右边,将U和V去掉后变为黑白视频
在这里插入图片描述
人类:对色度不敏感,对亮度敏感。Y表示亮度,UV表示色度

将Y去掉
在这里插入图片描述

音频采样数据格式

1、音频采样数据作用:保存了音频中的每一个采样点值
2、音频采样数据文件大小计算
例如:1分钟PCM格式歌曲
体积:60 (时间)* 44100(采样率,人的耳朵能够分辨的声音,一般情况下都是这个采样率) * 2(双声道) * 2(采样精度,16位) =11MB
3、音频采样数据查看工具:Audition

在这里插入图片描述

4、PCM格式
存储顺序:
在这里插入图片描述

命令行工具使用

FFmpge应用

提供了一套比较完整代码->开源免费
核心架构设计思想:(核心+插件)的设计

重要命令:
需要执行脚本如下图,可以去官网直接下载参考链接,也可以参考我的GitHub执行文件GitHub参考
在这里插入图片描述

  • ffmpeg.exe(视频压缩->转码来完成)
    作用:用于对视频进行转码操作
    例如:将mp4->mov,mov->mp4,wmv-mp4等
    命令格式:ffmpeg -i (指定输入文件路径) -b:v 输出视频码率 输出文件路径
    测试运行:将test.avi -> test.mp4

    在这里插入图片描述

注意:如果要改变音频或者视频码率,那么相对应的视频和音频码率都要做出改变,不然无法对应
比如:原始视频 视频码率 468 音频码率 128
改变视频 视频码率 234 音频码率 64

cd /Users/mac/Desktop/GitHub/iOS_AudioVideoProcessing/ffmpeg-test/ffmpeg-20181114-759589b-macos64-static/bin
./ffmpeg -i test.avi -b:v 234k -b:a 64k test.mp4

视频截取
注意时间格式

./ffmpeg -i test.mp4-ss 00:00:05 -t 00:00:10 test.mp4
  • ffplay.exe

作用:播放视频
格式: ffplay {文件路径}
例如:./ffplay test.avi

在这里插入图片描述

其他案例:视频,转为高质量GIF动图

命令:./ffmpeg -ss 00:00:03 -t 3 -i test.avi -r "15" dongtu.gif

解释:
1、./ffmpeg执行你目录下的程序脚本
2、-s 00:00:03 表示从第03秒开始制作gif,支持小数点,如果不加此命令,则从0秒开始
3、-t 3 表示把持续3秒的视频转换为gif,持续时间越长,gif文件格式越大,如果不加此命令,则把整个视频转换为GIF
4、-i 表示invert ,意为转换
5、test.avi 就是你需要转换的视频,名称最好不要用中文,不要留空格,支持多种视频格式
6、-s 640×360 GIF分辨率,如果不加此命令,分辨率不变。
7、-r "15"表示帧率,网上下载的视频帧率通常为24,设为15效果挺好了,帧率越高,体积越大,不加此命令,帧率保持不变
8、dongtu.gif输出文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好,针对您的问题,我可以给出如下思路: 1. 使用FFmpeg的C++ API来编码H264和AAC数据流,并将它们混合在一起。 2. 对于每个视频帧和音频帧,使用PTS(Presentation Time Stamp)来保证它们的时间戳是正确的。 3. 将编码后的H264和AAC数据流写入一个文件中,同时确保它们的时间戳是同步的。 下面是一个简单的示例代码,仅供参考: ``` #include <iostream> #include <string> #include <vector> #include <chrono> #include <thread> extern "C" { #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libavutil/opt.h> #include <libavutil/timestamp.h> #include <libavutil/audio_fifo.h> } #define AUDIO_SAMPLE_RATE 48000 #define AUDIO_CHANNELS 2 #define AUDIO_FORMAT AV_SAMPLE_FMT_FLT #define AUDIO_BITRATE 128000 using namespace std; int main(int argc, char* argv[]) { // Initialize FFmpeg av_register_all(); avcodec_register_all(); // Open video output file AVFormatContext* out_ctx; avformat_alloc_output_context2(&out_ctx, NULL, NULL, "output.mp4"); AVStream* video_stream = avformat_new_stream(out_ctx, NULL); AVStream* audio_stream = avformat_new_stream(out_ctx, NULL); // Configure video stream AVCodec* video_codec = avcodec_find_encoder(AV_CODEC_ID_H264); AVCodecContext* video_ctx = avcodec_alloc_context3(video_codec); video_ctx->bit_rate = 400000; video_ctx->width = 640; video_ctx->height = 480; video_ctx->time_base = { 1, 25 }; video_ctx->gop_size = 10; video_ctx->max_b_frames = 1; avcodec_open2(video_ctx, video_codec, NULL); avcodec_parameters_from_context(video_stream->codecpar, video_ctx); video_stream->time_base = video_ctx->time_base; // Configure audio stream AVCodec* audio_codec = avcodec_find_encoder(AV_CODEC_ID_AAC); AVCodecContext* audio_ctx = avcodec_alloc_context3(audio_codec); audio_ctx->sample_rate = AUDIO_SAMPLE_RATE; audio_ctx->channels = AUDIO_CHANNELS; audio_ctx->sample_fmt = AUDIO_FORMAT; audio_ctx->bit_rate = AUDIO_BITRATE; audio_ctx->time_base = { 1, AUDIO_SAMPLE_RATE }; avcodec_open2(audio_ctx, audio_codec, NULL); avcodec_parameters_from_context(audio_stream->codecpar, audio_ctx); audio_stream->time_base = audio_ctx->time_base; // Open output file avio_open(&out_ctx->pb, "output.mp4", AVIO_FLAG_WRITE); // Write header to output file avformat_write_header(out_ctx, NULL); // Encode and write frames to output file for (int i = 0; i < 100; i++) { // Encode video frame AVFrame* video_frame = av_frame_alloc(); video_frame->width = video_ctx->width; video_frame->height = video_ctx->height; video_frame->format = video_ctx->pix_fmt; av_frame_get_buffer(video_frame, 0); // Fill video frame with data... avcodec_send_frame(video_ctx, video_frame); AVPacket video_pkt; av_init_packet(&video_pkt); avcodec_receive_packet(video_ctx, &video_pkt); video_pkt.stream_index = video_stream->index; video_pkt.pts = i * video_ctx->time_base.den / (video_ctx->time_base.num * 25); video_pkt.dts = video_pkt.pts; av_interleaved_write_frame(out_ctx, &video_pkt); av_packet_unref(&video_pkt); av_frame_free(&video_frame); // Encode audio frame AVFrame* audio_frame = av_frame_alloc(); audio_frame->sample_rate = audio_ctx->sample_rate; audio_frame->channels = audio_ctx->channels; audio_frame->format = audio_ctx->sample_fmt; av_frame_get_buffer(audio_frame, 0); // Fill audio frame with data... avcodec_send_frame(audio_ctx, audio_frame); AVPacket audio_pkt; av_init_packet(&audio_pkt); avcodec_receive_packet(audio_ctx, &audio_pkt); audio_pkt.stream_index = audio_stream->index; audio_pkt.pts = i * audio_ctx->time_base.den / AUDIO_SAMPLE_RATE; audio_pkt.dts = audio_pkt.pts; av_interleaved_write_frame(out_ctx, &audio_pkt); av_packet_unref(&audio_pkt); av_frame_free(&audio_frame); // Sleep for a while to simulate real-time processing this_thread::sleep_for(chrono::milliseconds(40)); } // Write trailer to output file av_write_trailer(out_ctx); // Close output file avio_close(out_ctx->pb); avformat_free_context(out_ctx); // Cleanup FFmpeg avcodec_free_context(&video_ctx); avcodec_free_context(&audio_ctx); return 0; } ``` 在上述示例代码中,我们先初始化了FFmpeg,并创建了一个输出文件。然后,我们分别配置了视频流和音频流的编码参数,并将它们添加到输出文件中。接下来,我们编码并写入了100个视频帧和音频帧,并使用PTS保证它们的时间戳是正确的。最后,我们写入了输出文件的尾部,并关闭了输出文件。 请注意,上述示例代码仅供参考,您需要根据自己的实际需求进行修改和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值