录制最终格式是MP4,视频流是采用H264编码流,音频是aac编码流

最终需要将两个流合并到一个文件里

采用的方案,是通过mp4v2的库,进行合并

原理很简单:

先创建文件,输入编码参数

需要创建视频流初始

也需要创建音频流初始化

//创建MP4文件

mFileHandle = CreateMP4File(file,90000);   记住handle

//创建音频通道

MP4TrackId audio = MP4AddAudioTrack(mFileHandle, VOICE_RATE, 1024, MP4_MPEG4_AUDIO_TYPE);

//创建视频通道

mVideoId = MP4AddH264VideoTrack( mFileHandle,
                mTimeScale,
                mTimeScale / mFrameRate,
                mWidth,
                mHeight,
                nalu.data[1], /* sps[1] AVCProfileIndication */
                nalu.data[2], /* sps[2] profile_compat */
                nalu.data[3], /* sps[3] AVCLevelIndication */
                3);

然后按每帧内容存储至文件

看似简单,实际也有很多

1. 音频初始化参数设置

GetDecoderSpecificInfo

注意,他的参数含义,网上很多例子都是44.1k,因此,而参数里如果不细究,这个就会被忽略

auto config = GetDecoderSpecificInfo(2, 3, 2);

/*

参数1:AAC_LC-2;  这个表示音频编码

参数2:   48000-3,44100-4;

参数3:   2 channels : front - left, front - right

*/

/*添加aac音频*/MP4TrackId audio = MP4AddAudioTrack(mFileHandle, VOICE_RATE, 1024, MP4_MPEG4_AUDIO_TYPE);if (audio == MP4_INVALID_TRACK_ID){           errorf("add audio track failed.\n");return false;}mVoiceId = audio;MP4SetAudioProfileLevel(mFileHandle, 0x2);/*P1:AAC_LC-2; P2:48000-3,44100-4; P3:2 channels : front - left, front - right*/auto config = GetDecoderSpecificInfo(2, 3, 2);if(!MP4SetTrackESConfiguration(mFileHandle, audio, (uint8_t*) &config, 2)){errorf("set audio config failed=2 4 2\n");}

2. 视频初始化

视频编码库编码之后,会产生不同帧,需要解析nalu,不能直接存储

收到sps帧,需要对视频通道进行初始化

mVideoId = MP4AddH264VideoTrack( mFileHandle,mTimeScale,mTimeScale / mFrameRate,mWidth,mHeight,nalu.data[1], /* sps[1] AVCProfileIndication */nalu.data[2], /* sps[2] profile_compat */nalu.data[3], /* sps[3] AVCLevelIndication */3);           /* 4 bytes length before each NAL unit */if (mVideoId == MP4_INVALID_TRACK_ID){errorf("add video track failed.\n");return 0;}MP4SetVideoProfileLevel(mFileHandle, 0x7f); /*  main Profile @ Level 4 */MP4AddH264SequenceParameterSet(mFileHandle,mVideoId,nalu.data+4,nalu.size);

收到pps帧,需要设置参数

MP4AddH264PictureParameterSet(mFileHandle,mVideoId,nalu.data+4,nalu.size);

另外需要注意是同步帧信息

3. 时间戳概念

往往新手会忘记时间戳,但这个是神器,必须好好理解

比如说:视频设置是25帧/秒,如果实际采集只有20帧,或者在变化(一会20,一会25)类似这样。如果不设置时间戳,那么回放的时候会很奇怪,视频一会快一会慢(当然相差不大,裸眼很难分辨出来),但回放时间很真实,例如明明录制了30分钟,但实际回放的时候,只有29分钟。

因此要设置时间戳,时间戳的原点是创建通道的,后面每写入一帧数据,带入时间戳(相对第一个点的时间偏移)

音频也是

音频跟视频是分开两个通道的,因此,时间戳也是分开累计,同理,视频跟音频同步,也是基于时间戳!!

注意第5参数

if(!MP4WriteSample(mFileHandle, mVideoId, nalu.data, nalu.size+4, (now - mVideoTick) * 90, 0, isSync))
uint64_t timeStemp = (tickTime - mVoiceTick) * VOICE_RATE_STAMP;mVoiceTick = tickTime;if(!MP4WriteSample(mFileHandle, mVoiceId, buf, size, timeStemp, 0, 1))

视频采集到录制 - MP4生成相关推荐

  1. WebRTC系列--多路视频拼接及录制MP4

    文章目录 1. 数据获取介绍 1.1 一些概念 1.2 实现数据获取类 1.2.1 使用的类介绍 1.2.2 onFrame中使用工具介绍 2. 添加数据源source 2.1 peerConnect ...

  2. mp4是什么格式?如何录制mp4格式的视频?一招解决

    相信不少的小伙伴都听说过mp4格式,或者在日常的学习生活中就接触过不少mp4格式的文件.但也有不少的小伙伴还不是很了解mp4.mp4是什么格式?我们又该如何录制mp4格式的视频呢?今天小编教大家一招, ...

  3. mp4是什么格式?如何录制mp4格式的视频?

    案例:怎样录制mp4格式的视频? [我发现网上大部分视频都是mp4格式,我也想在电脑上录制mp4格式的视频.有没有小伙伴知道录制的方法?] 日常生活中,mp4格式已经成为了我们最常用的视频格式之一.它 ...

  4. JavaScript基于MediaRecorder录制mp4视频或webm视频并下载,JavaScript实现对video标签进行录制mp4视频或webm视频和下载

    前言 本章实现网页video标签录制mp4视频或webm视频并下载. 视频录制这种计算密集型任务比较重,比较适合放在后台进行实现,本章适合前端任务不太重的短时间视频录制,长时间录制建议还是走后台录制并 ...

  5. Android音视频之MediaRecorder录制视频

    1 MediaRecorder 录制视频步骤 这篇文章介绍了Android录音MediaRecorder使用和SoundPool的使用 主要讲解了音频的录制和播放,这篇AudioRecord和Audi ...

  6. iOS直播(三)GPUImage音视频采集并写入文件

    上一篇介绍了用GPUImage图像处理库进行图像采集,从而避免了直接使用AVFoundation(AVKit)时繁琐的代码,同时不用熟悉OpenGL ES也可以快速地对图像进行美颜.添加滤镜等.这一篇 ...

  7. 安卓 camera 调用流程_音视频开发之旅(四)Camera视频采集

    目录 Camera基础知识 视频采集的流程 遇到的问题和常见的坑(重点) 收获 一. Camera基础知识 Camera 有几个重要的基础概念. facing相机的方向,一般后置摄像头和前置摄像头. ...

  8. Android 音视频采集与软编码总结

    请尊重原创,转载请注明出处:http://blog.csdn.net/mabeijianxi/article/details/75807435(本文已在 "任玉刚" 微信公众号发布 ...

  9. WeBRTC IOS视频采集流程

    因CSDN MardDown语法问题,流程图部分不兼容有道云笔记,所以流程图部分请拷贝到有道云笔记生成查看. iOS视频录制: 同拍照一样视频录制功能有两种实现方式 UIImagePickerView ...

最新文章

  1. 从2D到3D的目标检测综述
  2. R语言使用ggplot2包使用geom_density()函数绘制密度图(连续色彩、离散色彩、梯度色彩)实战(density plot)
  3. 关于长江的题目_长江流域综合治理练习题
  4. Spring的Bean实例化、属性注入、对象注入、复杂注入(基于xml配置方式)
  5. 阻止JavaScript事件冒泡到父元素
  6. spring boot中利用mybatis-generator插件生成代码
  7. Google Chrome浏览器可能在您不知情的情况下破坏了您的测试
  8. CAS单点登陆原理简介及环境搭建
  9. java object 源码_java中Object类 源代码详解
  10. 听说你在学Python?来点PEP吧
  11. IDEA打包jar包将依赖包打包到一起
  12. Unity学习笔记——TimeLine的简单使用方法(一)
  13. Android Wear 2.0首款手表来了;工信部明确增加物联网网号 | IoT黑板报
  14. 使用python脚本将word文档转txt
  15. 记最近一周的一个支线任务
  16. Linux 远程工具 基础命令
  17. MATLAB(九)数值微积分
  18. USB VID 查询
  19. 人工智能时代,数据分析如何帮助预测业务未来?
  20. FLOPS和TOPS的区别 以及 算力的计算方法

热门文章

  1. 【开源工具】使用Whisper提取视频、语音的字幕
  2. 全国首张“跨省通办”结婚证在山东发出;奥动新能源2025年前在全国建1万座换电站 | 美通社头条...
  3. I. 知识图谱 应用案例 --- 美团
  4. excel 导入到access 提示索引或主关键字不能为空 但是表中的主关键字列并不是空的
  5. 开发中json的各种转换
  6. 杰卡德相似度(Jaccard similarity)
  7. 海信、格力、小米、科沃斯等空气净化器的“小涨潮”,难掩行业“大退潮”之下的尴尬
  8. 【目标检测】|MobileNet
  9. 最好用的浏览器主页Speedceo——检索不套路
  10. 白马美的的“红利间歇期”