MP4 Muxer
一、mp4的几种封装方案
1、ffmpeg
2、mp4v2
3、gpac
https://blog.csdn.net/LLL347/article/details/85886975
https://blog.csdn.net/weixin_43549602/article/details/84571906
二、mp4v2
通过EasyAACEncoder + mp4v2, 根据两位老哥的代码,整合了个demo.
main.cpp
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include "EasyAACEncoderAPI.h" #include "mp4v2.h" #include "util.h" /*test file*/ static off_t file_size; static char* get_h264_frame(char* raw_file) { int raw_fd = open(raw_file, O_RDONLY); if (raw_fd < 0) { printf("open h264 raw file %s failed.\n", raw_file); return nullptr; } file_size = lseek(raw_fd, 0, SEEK_END); if (file_size <= 0) { printf("h264 raw file %s empty.\n", raw_file); return nullptr; } char*h264_raw = (char*)malloc(file_size); if (!h264_raw) { printf("alloc raw buffer failed for file %s.\n", raw_file); return nullptr; } lseek(raw_fd, 0, SEEK_SET); ssize_t nb_read = 0; if ((nb_read = read(raw_fd, h264_raw, file_size)) != file_size) { printf("buffer %s failed, expect=%dKB, actual=%dKB.\n", raw_file, (int)(file_size / 1024), (int)(nb_read / 1024)); return nullptr; } close(raw_fd); return h264_raw; } /*example*/ int main(int argc, char** argv) { int fps = 25; /*g711 data source*/ int n = 0; char g711a[320]; FILE *infile=fopen("./doc/stream-file/8k_1_16.g711a","rb"); /*g711_to_aac*/ InitParam initParam; initParam.u32AudioSamplerate=8000; initParam.ucAudioChannel=1; initParam.u32PCMBitSize=16; initParam.ucAudioCodec = Law_ALaw; Easy_Handle handle = Easy_AACEncoder_Init(initParam); int bAACBufferSize = 4*1024; unsigned char *pbAACBuffer = (unsigned char*)malloc(bAACBufferSize * sizeof(unsigned char)); unsigned int aac_len = 0; /*Create */ //MP4FileHandle mp4 = MP4CreateEx("test.mp4", MP4_DETAILS_ALL, 0, 1, 1, 0, 0, 0, 0); MP4FileHandle mp4 = MP4Create("test.mp4", 0); MP4SetTimeScale(mp4, 90000); /*Set video*/ MP4TrackId video = MP4AddH264VideoTrack(mp4, 90000, 90000 / fps, 640, 480, 0x64, //sps[1] AVCProfileIndication 0x00, //sps[2] profile_compat 0x1f, //sps[3] AVCLevelIndication 3); MP4SetVideoProfileLevel(mp4, 0x7F); /*Set audio*/ MP4TrackId audio = MP4AddAudioTrack(mp4, 8000, 1024, MP4_MPEG4_AUDIO_TYPE); MP4SetAudioProfileLevel(mp4, 0x2); while(1){ if(fread(g711a,1,320,infile) > 0) { if(Easy_AACEncoder_Encode(handle, (unsigned char*)g711a, 320, pbAACBuffer, &aac_len) > 0) { dump_bin("ttt.aac",(char*)pbAACBuffer, aac_len); MP4WriteSample(mp4, audio, pbAACBuffer, aac_len, MP4_INVALID_DURATION, 0, 1); } }else{ fseek(infile, 0, SEEK_SET); continue; } char str[32]; sprintf(str,"./doc/stream-file/h264_3/%d",n); char* h264_raw = get_h264_frame(str); if(h264_raw != nullptr){ MP4WriteSample(mp4,video , (uint8_t*)h264_raw, file_size, MP4_INVALID_DURATION, 0, 1); } free(h264_raw); if(++n > 311) break; } Easy_AACEncoder_Release(handle); free(pbAACBuffer); MP4Close(mp4); return 0; }
Makefile
APP = main INCLUDE = \ -I ./lib/EasyAACEncoder/include \ -I ./lib/mp4v2/include \ -I ./lib/mp4v2/include/mp4v2 \ -I ./lib/util LIB = \ ./lib/EasyAACEncoder/lib/libEasyAACEncoder.a \ ./lib/mp4v2/lib/libmp4v2.a SRC = main.cpp \ ./lib/util/util.c CFLAGS = -g -O0 -std=c++11 -lstdc++ LDFLAGS = -lpthread -lz out: g++ $(SRC) -o $(APP) $(LIB) $(INCLUDE) $(CFLAGS) $(LDFLAGS) clean: rm -rf *o *.out $(APP)
封装一下

参考
1. 先是随手一搜,看起来应该很简单,不过mp4v2只是勉强能用,最好还是用ffmpeg
https://blog.csdn.net/lipku/article/details/78138645
https://github.com/EasyDarwin/EasyAACEncoder
三、ffmpeg
1. mp4 muxer
https://github.com/slmax2017/ffmpeg_mp4_h264_mux
end

浙公网安备 33010602011771号