ireader / media-server

RTSP/RTP/RTMP/FLV/HLS/MPEG-TS/MPEG-PS/MPEG-DASH/MP4/fMP4/MKV/WebM
MIT License
3.03k stars 1.07k forks source link

fmp4增加音频时无法录制进文件 #344

Closed lilei-John closed 1 month ago

lilei-John commented 1 month ago

2024_07_15_10_30_35.zip

上传的文件中包含一个mp4录像文件和一个aac文件,使用方法为 switch (payload) {         case LC_PT_AAC:             source                              = MOV_OBJECT_AAC;             struct mpeg4_aac_t aac              = {0};             unsigned char      extra_data[1024] = {0};             mpeg4_aac_adts_load((unsigned char *)data, len, &aac);             LC_S32 extra_data_size = mpeg4_aac_audio_specific_config_save(&aac, extra_data, sizeof(extra_data));             if (extra_data_size > 0) {                 LOGD("AVCDecoderConfigurationRecord save success %d", extra_data_size);             } else {                 LOGD("AVCDecoderConfigurationRecord fail");                 return LC_FAILURE;             }             LC_S32 rate               = mpeg4_aac_audio_frequency_to((enum mpeg4_aac_frequency)aac.sampling_frequency_index);             recordHandle->audio_track = fmp4_writer_add_audio(recordHandle->mov, source, channel_count, bit_per_sample, rate, extra_data, extra_data_size);             break;         case LC_PT_G711A:             source                    = MOV_OBJECT_G711a;             recordHandle->audio_track = fmp4_writer_add_audio(recordHandle->mov, source, channel_count, bit_per_sample, sample_rate, NULL, 0);             break;         case LC_PT_G711U:             source                    = MOV_OBJECT_G711u;             recordHandle->audio_track = fmp4_writer_add_audio(recordHandle->mov, source, channel_count, bit_per_sample, sample_rate, NULL, 0);             break;         case LC_PT_OPUS:             source = MOV_OBJECT_OPUS;             break;     }

经过打印extra_data_size为2,使用mp4info也未发现任何audio track信息

lilei-John commented 1 month ago

我把fmp4_writer_create(mov_file_buffer(), &(recordHandle->fd), MOV_FLAG_FASTSTART | MOV_FLAG_SEGMENT);改成fmp4_writer_create(mov_file_buffer(), &(recordHandle->fd), MOV_FLAG_FASTSTART );后可以录音频了,暂时不明白这些参数的意思,还有一个问题,这个fmp4只能用vlc播放不能用windows自带的播放器播放,不知道原因。且用mp4info查看 Track Type Info 1 video H264 Baseline@3.1, 0.000 secs, 0 kbps, 1280x720 @ 0.000000 fps 2 audio MPEG-4 AAC LC, 0.000 secs, 88 kbps, 1000 Hz 音视频关键信息没有填入如视频帧率,音频采样率

ireader commented 1 month ago

mp4不能完全算流媒体格式,要求在写入音视频帧之前,一次性先调用fmp4_writer_add_audio /fmp4_writer_add_video 接口创建音视频track。

调用顺序大致如下:

  1. fmp4_writer_add_video
  2. fmp4_writer_add_audio
  3. fmp4_writer_init_segment
  4. fmp4_writer_write(video)
  5. fmp4_write_write(audio)
lilei-John commented 1 month ago

是按照这个顺序写的,我发现和 int mov_add_audio(struct mov_track_t track, const struct mov_mvhd_t mvhd, uint32_t timescale, uint8_t object, int channel_count, int bits_per_sample, int sample_rate, const void *extra_data, size_t extra_data_size) 这个代码的track->mdhd.timescale = timescale;相关,这个默认是1000,改成16000也会变成16000 Hz Track Type Info 1 video H264 Baseline@3.1, 0.000 secs, 0 kbps, 1280x720 @ 0.000000 fps 2 audio MPEG-4 AAC LC, 0.000 secs, 88 kbps, 16000 Hz mp4file 2024_07_15_18_06_31.mp4, track 1, samples 0, timescale 1000 mp4file 2024_07_15_18_06_31.mp4, track 2, samples 0, timescale 16000 感觉有些参数似乎不标准导致,我尝试使用ffmpeg制作fmp4是可以在windwos的自带播放器播放,参考附件ffmpeg.mp4

ffmpeg.zip

lilei-John commented 1 month ago

2024_07_15_18_06_31.zip 这个是我自己录制的

ireader commented 1 month ago

image

2024_07_15_18_06_31 这个文件写入mp4时码流是annexb,转换成avcc再试试。

lilei-John commented 1 month ago

感谢指点,现在已经可以在windows上播放了,但是播放视频比较卡,vlc比较流畅。ffmpeg生成的windows播放器播放也比较流畅 2024_07_16_16_32_41.zip

ireader commented 1 month ago

image

从解析的数据看,周期性的有一些aac时间戳跳变,你可以把写入的音视频帧时间戳都打印输出看看。

确保输入的音视频时间戳是一致的。

lilei-John commented 1 month ago

这个查了下使用的mpeg4_aac_adts_frame_length函数导致的数据大小发生了改变,如果不调用这个去掉7个字节头后pts是均匀的 2024_07_17_03_12_01.zip image

lilei-John commented 1 month ago

这个问题已经解决了,是我的aac文件的采样率是16000但是时间戳不是16k的间隔.我还有一个问题,目前这个文件是通过实时流的方式录制录像时长一直是0,看了下默认moov初始化只写一次,如果我在录文件结束时再写一次moov如果断电的话这个文件是会不可读吧有什么办法解决呢

ireader commented 1 month ago
3a817feb9e2de3814cece79ec8d7a36

可以把fmp4-writer.c文件的39行注释后再试试。

lilei-John commented 1 month ago

image 还是0

ireader commented 1 month ago

duration值不会修改,可以看看播放器能否读出文件时长。

lilei-John commented 1 month ago

vlc可以但是windos自带的播放器不行

ireader commented 1 month ago

ffmpeg生成fmp4文件,windows自带播放器能显示文件时长吗?

lilei-John commented 1 month ago

ffmpeg生成的也不显示,如果用户想在windows跳帧播放可能不行,所以我一开始想的在录像结束时再写一次moov但是担心断电会导致文件moov丢失。没有好的方法我再想想方法

lilei-John commented 1 month ago

感谢大佬的支持!