音视频FLV合成实战

FFmpeg合成流程

示例本程序会⽣成⼀个合成的⾳频和视频流,并将它们编码和封装输出到输出⽂件,输出格式是根据⽂件 扩展名⾃动猜测的。

示例的流程图如下所示。

C++音视频开发学习资料点击领取音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

ffmpeg 的 Mux 主要分为 三步操作:

avformat_write_header : 写⽂件头

av_write_frame/av_interleaved_write_frame: 写packet

av_write_trailer : 写⽂件尾

avcodec_parameters_from_context:

将AVCodecContext结构体中码流参数拷⻉到AVCodecParameters结构体中,和avcodec_parameters_to_context刚好相反。

FFmpeg函数:avformat_write_header

int avformat_write_header(AVFormatContext *s, AVDictionary **options){    int ret = 0;    int already_initialized = s->internal->initialized;    int streams_already_initialized = s->internal->streams_initialized;    if (!already_initialized)        if ((ret = avformat_init_output(s, options)) < 0)            return ret;    if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)        avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER);    if (s->oformat->write_header) {        ret = s->oformat->write_header(s);        if (ret >= 0 && s->pb && s->pb->error < 0)            ret = s->pb->error;        if (ret < 0)            goto fail;        flush_if_needed(s);    }    if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)        avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN);    if (!s->internal->streams_initialized) {        if ((ret = init_pts(s)) < 0)            goto fail;    }    return streams_already_initialized;fail:    if (s->oformat->deinit)        s->oformat->deinit(s);    return ret;}

最终调⽤到复⽤器的 write_header,⽐如

AVOutputFormat ff_flv_muxer = {    .name           = "flv",    .long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),    .mime_type      = "video/x-flv",    .extensions     = "flv",    .priv_data_size = sizeof(FLVContext),    .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF,    .video_codec    = AV_CODEC_ID_FLV1,    .init           = flv_init,    .write_header   = flv_write_header,    .write_packet   = flv_write_packet,    .write_trailer  = flv_write_trailer,    .check_bitstream= flv_check_bitstream,    .codec_tag      = (const AVCodecTag* const []) {                          flv_video_codec_ids, flv_audio_codec_ids, 0                      },    .flags          = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |                      AVFMT_TS_NONSTRICT,    .priv_class     = &flv_muxer_class,};

FFmpeg结构体:avformat_alloc_output_context2

函数在在libavformat.h⾥⾯的定义

C++音视频开发学习资料点击领取音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

/** * Allocate an AVFormatContext for an output format. * avformat_free_context() can be used to free the context and * everything allocated by the framework within it. *  * @param *ctx is set to the created format context, or to NULL in * case of failure * @param oformat format to use for allocating the context, if NULL * format_name and filename are used instead * @param format_name the name of output format to use for allocating the * context, if NULL filename is used instead * @param filename the name of the filename to use for allocating the * context, may be NULL * @return >= 0 in case of success, a negative AVERROR code in case of * failure */int avformat_alloc_output_context2(AVFormatContext **ctx, ff_const59 AVOutputFormat *oformat,                                   const char *format_name, const char *filename);

函数参数的介绍:

ctx:需要创建的context,返回NULL表示失败。

oformat:指定对应的AVOutputFormat,如果不指定,可以通过后⾯format_name、filename两个参 数进⾏指定,让ffmpeg⾃⼰推断。

format_name: 指定⾳视频的格式,⽐如“flv”,“mpeg”等,如果设置为NULL,则由filename进⾏指 定,让ffmpeg⾃⼰推断。

filename: 指定⾳视频⽂件的路径,如果oformat、format_name为NULL,则ffmpeg内部根据 filename后缀名选择合适的复⽤器,⽐如xxx.flv则使⽤flv复⽤器。

int avformat_alloc_output_context2(AVFormatContext **avctx, ff_const59 AVOutputFormat *oformat,                                   const char *format, const char *filename){    AVFormatContext *s = avformat_alloc_context();    int ret = 0;    *avctx = NULL;    if (!s)        goto nomem;    if (!oformat) {        if (format) {            oformat = av_guess_format(format, NULL, NULL);            if (!oformat) {                av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format
", format);                ret = AVERROR(EINVAL);                goto error;            }        } else {            oformat = av_guess_format(NULL, filename, NULL);            if (!oformat) {                ret = AVERROR(EINVAL);                av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'
",                       filename);                goto error;            }        }    }    s->oformat = oformat;    if (s->oformat->priv_data_size > 0) {        s->priv_data = av_mallocz(s->oformat->priv_data_size);        if (!s->priv_data)            goto nomem;        if (s->oformat->priv_class) {            *(const AVClass**)s->priv_data= s->oformat->priv_class;            av_opt_set_defaults(s->priv_data);        }    } else        s->priv_data = NULL;    if (filename) {#if FF_API_FORMAT_FILENAMEFF_DISABLE_DEPRECATION_WARNINGS        av_strlcpy(s->filename, filename, sizeof(s->filename));FF_ENABLE_DEPRECATION_WARNINGS#endif        if (!(s->url = av_strdup(filename)))            goto nomem;    }    *avctx = s;    return 0;nomem:    av_log(s, AV_LOG_ERROR, "Out of memory
");    ret = AVERROR(ENOMEM);error:    avformat_free_context(s);    return ret;}

可以看出,⾥⾯最主要的就两个函数,avformat_alloc_context和av_guess_format,⼀个 是申请内存分配上下⽂,⼀个是通过后⾯两个参数获取AVOutputFormat。

出av_guess_format这个函数会通过filename和short_name来和所有的编码器进⾏⽐对,找 出最接近的编码器然后返回。

ff_const59 AVOutputFormat *av_guess_format(const char *short_name, const char *filename,                                const char *mime_type){    const AVOutputFormat *fmt = NULL;    AVOutputFormat *fmt_found = NULL;    void *i = 0;    int score_max, score;    /* specific test for image sequences */#if CONFIG_IMAGE2_MUXER    if (!short_name && filename &&        av_filename_number_test(filename) &&        ff_guess_image2_codec(filename) != AV_CODEC_ID_NONE) {        return av_guess_format("image2", NULL, NULL);    }#endif    /* Find the proper file type. */    score_max = 0;    while ((fmt = av_muxer_iterate(&i))) {        score = 0;        if (fmt->name && short_name && av_match_name(short_name, fmt->name))            score += 100;        if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))            score += 10;        if (filename && fmt->extensions &&            av_match_ext(filename, fmt->extensions)) {            score += 5;        }        if (score > score_max) {            score_max = score;            fmt_found = (AVOutputFormat*)fmt;        }    }    return fmt_found;}

FFmpeg结构体:AVOutputFormat

C++音视频开发学习资料点击领取音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

1.描述

AVOutpufFormat表示输出⽂件容器格式,AVOutputFormat 结构主要包含的信息有:封装名称描述,编 码格式信息(video/audio 默认编码格式,⽀持的编码格式列表),⼀些对封装的操作函数 (write_header,write_packet,write_tailer等)。 ffmpeg⽀持各种各样的输出⽂件格式,MP4,FLV,3GP等等。⽽ AVOutputFormat 结构体则保存了这 些格式的信息和⼀些常规设置。 每⼀种封装对应⼀个 AVOutputFormat 结构,ffmpeg将AVOutputFormat 按照链表存储:

2.结构体定义

/** * @addtogroup lavf_encoding * @{ */typedef struct AVOutputFormat {    const char *name;    /**     * Descriptive name for the format, meant to be more human-readable     * than name. You should use the NULL_IF_CONFIG_SMALL() macro     * to define it.     */    const char *long_name;    const char *mime_type;    const char *extensions; /**< comma-separated filename extensions */    /* output support */    enum AVCodecID audio_codec;    /**< default audio codec */    enum AVCodecID video_codec;    /**< default video codec */    enum AVCodecID subtitle_codec; /**< default subtitle codec */    /**     * can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER,     * AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS,     * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH,     * AVFMT_TS_NONSTRICT, AVFMT_TS_NEGATIVE     */    int flags;    /**     * List of supported codec_id-codec_tag pairs, ordered by "better     * choice first". The arrays are all terminated by AV_CODEC_ID_NONE.     */    const struct AVCodecTag * const *codec_tag;    const AVClass *priv_class; ///< AVClass for the private context    /*****************************************************************     * No fields below this line are part of the public API. They     * may not be used outside of libavformat and can be changed and     * removed at will.     * New public fields should be added right above.     *****************************************************************     */    /**     * The ff_const59 define is not part of the public API and will     * be removed without further warning.     */#if FF_API_AVIOFORMAT#define ff_const59#else#define ff_const59 const#endif    ff_const59 struct AVOutputFormat *next;    /**     * size of private data so that it can be allocated in the wrapper     */    int priv_data_size;    int (*write_header)(struct AVFormatContext *);    /**     * Write a packet. If AVFMT_ALLOW_FLUSH is set in flags,     * pkt can be NULL in order to flush data buffered in the muxer.     * When flushing, return 0 if there still is more data to flush,     * or 1 if everything was flushed and there is no more buffered     * data.     */    int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);    int (*write_trailer)(struct AVFormatContext *);    /**     * Currently only used to set pixel format if not YUV420P.     */    int (*interleave_packet)(struct AVFormatContext *, AVPacket *out,                             AVPacket *in, int flush);    /**     * Test if the given codec can be stored in this container.     *     * @return 1 if the codec is supported, 0 if it is not.     *         A negative number if unknown.     *         MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC     */    int (*query_codec)(enum AVCodecID id, int std_compliance);    void (*get_output_timestamp)(struct AVFormatContext *s, int stream,                                 int64_t *dts, int64_t *wall);    /**     * Allows sending messages from application to device.     */    int (*control_message)(struct AVFormatContext *s, int type,                           void *data, size_t data_size);    /**     * Write an uncoded AVFrame.     *     * See av_write_uncoded_frame() for details.     *     * The library will free *frame afterwards, but the muxer can prevent it     * by setting the pointer to NULL.     */    int (*write_uncoded_frame)(struct AVFormatContext *, int stream_index,                               AVFrame **frame, unsigned flags);    /**     * Returns device list with it properties.     * @see avdevice_list_devices() for more details.     */    int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list);    /**     * Initialize device capabilities submodule.     * @see avdevice_capabilities_create() for more details.     */    int (*create_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);    /**     * Free device capabilities submodule.     * @see avdevice_capabilities_free() for more details.     */    int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps);    enum AVCodecID data_codec; /**< default data codec */    /**     * Initialize format. May allocate data here, and set any AVFormatContext or     * AVStream parameters that need to be set before packets are sent.     * This method must not write output.     *     * Return 0 if streams were fully configured, 1 if not, negative AVERROR on failure     *     * Any allocations made here must be freed in deinit().     */    int (*init)(struct AVFormatContext *);    /**     * Deinitialize format. If present, this is called whenever the muxer is being     * destroyed, regardless of whether or not the header has been written.     *     * If a trailer is being written, this is called after write_trailer().     *     * This is called if init() fails as well.     */    void (*deinit)(struct AVFormatContext *);    /**     * Set up any necessary bitstream filtering and extract any extra data needed     * for the global header.     * Return 0 if more packets from this stream must be checked; 1 if not.     */    int (*check_bitstream)(struct AVFormatContext *, const AVPacket *pkt);} AVOutputFormat;

3.常用变量及其作⽤

const char *name; // 复⽤器名称

const char *long_name;//格式的描述性名称,易于阅读。

enum AVCodecID audio_codec; //默认的⾳频编解码器

enum AVCodecID video_codec; //默认的视频编解码器

enum AVCodecID subtitle_codec; //默认的字幕编解码器

⼤部分复⽤器都有默认的编码器,所以⼤家如果要调整编码器类型则需要⾃⼰⼿动指定。

比如

AVOutputFormat ff_flv_muxer = {    .name           = "flv",    .long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),    .mime_type      = "video/x-flv",    .extensions     = "flv",    .priv_data_size = sizeof(FLVContext),    .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF,    .video_codec    = AV_CODEC_ID_FLV1,    .init           = flv_init,    .write_header   = flv_write_header,    .write_packet   = flv_write_packet,    .write_trailer  = flv_write_trailer,    .check_bitstream= flv_check_bitstream,    .codec_tag      = (const AVCodecTag* const []) {                          flv_video_codec_ids, flv_audio_codec_ids, 0                      },    .flags          = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS |                      AVFMT_TS_NONSTRICT,    .priv_class     = &flv_muxer_class,};
AVOutputFormat ff_mpegts_muxer = {    .name           = "mpegts",    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"),    .mime_type      = "video/MP2T",    .extensions     = "ts,m2t,m2ts,mts",    .priv_data_size = sizeof(MpegTSWrite),    .audio_codec    = AV_CODEC_ID_MP2,    .video_codec    = AV_CODEC_ID_MPEG2VIDEO,    .init           = mpegts_init,    .write_packet   = mpegts_write_packet,    .write_trailer  = mpegts_write_end,    .deinit         = mpegts_deinit,    .check_bitstream = mpegts_check_bitstream,    .flags          = AVFMT_ALLOW_FLUSH | AVFMT_VARIABLE_FPS | AVFMT_NODIMENSIONS,    .priv_class     = &mpegts_muxer_class,};

int (*write_header)(struct AVFormatContext *);

int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);//写⼀个数据包。 如果在标志中设 置AVFMT_ALLOW_FLUSH,则pkt可以为NULL。

int (*write_trailer)(struct AVFormatContext *);

int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, AVPacket *in, int flush);

int (*control_message)(struct AVFormatContext *s, int type, void *data, size_t data_size);//允 许从应⽤程序向设备发送消息。

int (*write_uncoded_frame)(struct AVFormatContext *, int stream_index, AVFrame **frame, unsigned flags);//写⼀个未编码的AVFrame。

int (*init)(struct AVFormatContext *);//初始化格式。 可以在此处分配数据,并设置在发送数据包之前 需要设置的任何AVFormatContext或AVStream参数。

void (*deinit)(struct AVFormatContext *);//取消初始化格式。

int (*check_bitstream)(struct AVFormatContext *, const AVPacket *pkt);//设置任何必要的⽐特流 过滤,并提取全局头部所需的任何额外数据。

FFmpeg函数:avformat_new_stream

AVStream 即是流通道。例如我们将 H264 和 AAC 码流存储为MP4⽂件的时候,就需要在 MP4⽂件中 增加两个流通道,⼀个存储Video:H264,⼀个存储Audio:AAC。(假设H264和AAC只包含单个流通道)。

/** * Add a new stream to a media file. *  * When demuxing, it is called by the demuxer in read_header(). If the * flag AVFMTCTX_NOHEADER is set in s.ctx_flags, then it may also * be called in read_packet(). *  * When muxing, should be called by the user before avformat_write_header(). *  * User is required to call avcodec_close() and avformat_free_context() to * clean up the allocation by avformat_new_stream(). *  * @param s media file handle * @param c If non-NULL, the AVCodecContext corresponding to the new stream * will be initialized to use this codec. This is needed for e.g. codec-specific * defaults to be set, so codec should be provided if it is known. *  * @return newly created stream or NULL on error. */AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c);

avformat_new_stream 在 AVFormatContext 中创建 Stream 通道。

关联的结构体

AVFormatContext :

unsigned int nb_streams; 记录stream通道数⽬。

AVStream **streams; 存储stream通道。

AVStream : int index; 在AVFormatContext 中所处的通道索引

avformat_new_stream之后便在 AVFormatContext ⾥增加了 AVStream 通道(相关的index已经被设 置了)。之后,我们就可以⾃⾏设置 AVStream 的⼀些参数信息。例如 : codec_id , format ,bit_rate ,width , height

FFmpeg函数:av_interleaved_write_frame

C++音视频开发学习资料点击领取音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)

函数原型:int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);

说明:将数据包写⼊输出媒体⽂件,并确保正确的交织(保持packet dts的增⻓性)。 该函数会在内部根据需要缓存packet,以确保输出⽂件中的packet按dts递增的顺序正确交织。如果⾃⼰ 进⾏交织则应调⽤av_write_frame()。

参数:

返回值:成功时为0,错误时为负AVERROR。即使此函数调⽤失败,Libavformat仍将始终释放该 packet。

FFmpeg函数:av_compare_ts

/** * Compare two timestamps each in its own time base. *  * @return One of the following values: *         - -1 if `ts_a` is before `ts_b` *         - 1 if `ts_a` is after `ts_b` *         - 0 if they represent the same position *  * @warning * The result of the function is undefined if one of the timestamps is outside * the `int64_t` range when represented in the other's timebase. */int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b);

返回值:

-1 ts_a 在ts_b之前

1 ts_a 在ts_b之后

0 ts_a 在ts_b同⼀位置

⽤伪代码:return ts_a == ts_b ? 0 : ts_a < ts_b ? -1 : 1

MediaInfo分析⽂件写⼊

这⾥只是分析avformat_write_header和av_write_trailer的作⽤。

flv

只写avformat_write_header

000 File Header (9 bytes) 000 FLV header (9 bytes) 000 Signature: FLV 003 Version: 1 (0x01) 004 Flags: 5 (0x05) 005 Video: Yes 005 Audio: Yes 005 Size: 9 (0x00000009) 009 ------------------------- 009 --- FLV, accepted --- 009 ------------------------- 009 Meta - onMetaData - 12 elements (288 bytes) 009 Header (15 bytes) 009 PreviousTagSize: 0 (0x00000000) 00D Type: 18 (0x12) 00E BodyLength: 273 (0x000111) 011 Timestamp_Base: 0 (0x000000) 014 Timestamp_Extended: 0 (0x00) 015 StreamID: 0 (0x000000) 018 Type: 2 (0x02) - SCRIPTDATASTRING 019 Value_Size: 10 (0x000A) 01B Value: onMetaData 025 Type: 8 (0x08) -SCRIPTDATAVARIABLE[ECMAArrayLength] 026 ECMAArrayLength: 12 (0x0000000C) 02A duration (19 bytes) 02A StringLength: 8 (0x0008) 02C StringData: duration 034 Type: 0 (0x00) - DOUBLE 035 Value: 0.000 03D width - 352 (16 bytes) 03D StringLength: 5 (0x0005) 03F StringData: width044 Type: 0 (0x00) - DOUBLE 045 Value: 352.000 04D height - 288 (17 bytes) 04D StringLength: 6 (0x0006) 04F StringData: height 055 Type: 0 (0x00) - DOUBLE 056 Value: 288.000 05E videodatarate - 390625 (24 bytes) 05E StringLength: 13 (0x000D) 060 StringData: videodatarate 06D Type: 0 (0x00) - DOUBLE 06E Value: 390.625 076 videocodecid - 2 (23 bytes) 076 StringLength: 12 (0x000C) 078 StringData: videocodecid 084 Type: 0 (0x00) - DOUBLE 085 Value: 2.000 08D audiodatarate - 62500 (24 bytes) 08D StringLength: 13 (0x000D) 08F StringData: audiodatarate 09C Type: 0 (0x00) - DOUBLE 09D Value: 62.500 0A5 audiosamplerate - 44100 (26 bytes) 0A5 StringLength: 15 (0x000F) 0A7 StringData: audiosamplerate 0B6 Type: 0 (0x00) - DOUBLE 0B7 Value: 44100.000 0BF audiosamplesize - 16 (26 bytes) 0BF StringLength: 15 (0x000F) 0C1 StringData: audiosamplesize 0D0 Type: 0 (0x00) - DOUBLE 0D1 Value: 16.000 0D9 stereo - 1 (0x1) (10 bytes) 0D9 StringLength: 6 (0x0006) 0DB StringData: stereo 0E1 Type: 1 (0x01) - UI8 0E2 Value: 1 (0x01) 0E3 audiocodecid - 2 (23 bytes) 0E3 StringLength: 12 (0x000C) 0E5 StringData: audiocodecid0F1 Type: 0 (0x00) - DOUBLE 0F2 Value: 2.000 0FA encoder - Lavf58.29.100 (25 bytes) 0FA StringLength: 7 (0x0007) 0FC StringData: encoder 103 Type: 2 (0x02) - SCRIPTDATASTRING 104 Value_Size: 13 (0x000D) 106 Value: Lavf58.29.100 113 filesize (19 bytes) 113 StringLength: 8 (0x0008) 115 StringData: filesize 11D Type: 0 (0x00) - DOUBLE 11E Value: 0.000 129 End Of File (4 bytes) 129 Header (4 bytes) 129 PreviousTagSize: 284 (0x0000011C) 12D ------------------------ 12D --- FLV, filling --- 12D ------------------------ 12D ------------------------- 12D --- FLV, finished --- 12D -------------------------

avformat_write_header+ av_write_trailer 对于FLV⽽⾔没有任何变化。

mp4

avformat_write_header

00 File Type (32 bytes) 00 Header (8 bytes) 00 Size: 32 (0x00000020) 04 Name: ftyp 08 MajorBrand: isom 0C MajorBrandVersion: 512 (0x00000200) 10 CompatibleBrand: isom 14 CompatibleBrand: iso2 18 CompatibleBrand: avc1 1C CompatibleBrand: mp41 20 ----------------------------20 --- MPEG-4, accepted --- 20 ---------------------------- 20 Free space (8 bytes) 20 Header (8 bytes) 20 Size: 8 (0x00000008) 24 Name: free 28 Junk (4 bytes) 28 Header (4 bytes) 28 Size: 0 (0x00000000) 2C Problem (4 bytes) 2C Header (4 bytes) 2C Size: 1835295092 (0x6D646174) 30 Size is wrong: 0 (0x00000000) 30 --------------------------- 30 --- MPEG-4, filling --- 30 --------------------------- 30 ---------------------------- 30 --- MPEG-4, finished --- 30 ----------------------------

avformat_write_header+av_write_trailer

000 File Type (32 bytes) 000 Header (8 bytes) 000 Size: 32 (0x00000020) 004 Name: ftyp 008 MajorBrand: isom 00C MajorBrandVersion: 512 (0x00000200) 010 CompatibleBrand: isom 014 CompatibleBrand: iso2 018 CompatibleBrand: avc1 01C CompatibleBrand: mp41 020 ---------------------------- 020 --- MPEG-4, accepted --- 020 ---------------------------- 020 Free space (8 bytes) 020 Header (8 bytes) 020 Size: 8 (0x00000008) 024 Name: free 028 Data (8 bytes)028 Header (8 bytes) 028 Size: 8 (0x00000008) 02C Name: mdat 030 File header (214 bytes) 030 Header (8 bytes) 030 Size: 214 (0x000000D6) 034 Name: moov 038 Movie header (108 bytes) 038 Header (8 bytes) 038 Size: 108 (0x0000006C) 03C Name: mvhd 040 Version: 0 (0x00) 041 Flags: 0 (0x000000) 044 Creation time: 0 (0x00000000) - 048 Modification time: 0 (0x00000000) - 04C Time scale: 1000 (0x000003E8) - 1000 Hz 050 Duration: 0 (0x00000000) - 0 ms 054 Preferred rate: 65536 (0x00010000) - 1.000 058 Preferred volume: 256 (0x0100) - 1.000 05A Reserved: (10 bytes) 064 Matrix structure (36 bytes) 064 a (width scale): 1.000 068 b (width rotate): 0.000 06C u (width angle): 0.000 070 c (height rotate): 0.000 074 d (height scale): 1.000 078 v (height angle): 0.000 07C x (position left): 0.000 080 y (position top): 0.000 084 w (divider): 1.000 088 Preview time: 0 (0x00000000) 08C Preview duration: 0 (0x00000000) 090 Poster time: 0 (0x00000000) 094 Selection time: 0 (0x00000000) 098 Selection duration: 0 (0x00000000) 09C Current time: 0 (0x00000000) 0A0 Next track ID: 2 (0x00000002) 0A4 User Data (98 bytes) 0A4 Header (8 bytes) 0A4 Size: 98 (0x00000062)0A8 Name: udta 0AC Metadata (90 bytes) 0AC Header (8 bytes) 0AC Size: 90 (0x0000005A) 0B0 Name: meta 0B4 Version: 0 (0x00) 0B5 Flags: 0 (0x000000) 0B8 Metadata Header (33 bytes) 0B8 Header (8 bytes) 0B8 Size: 33 (0x00000021) 0BC Name: hdlr 0C0 Version: 0 (0x00) 0C1 Flags: 0 (0x000000) 0C4 Type (Quicktime): 0C8 Metadata type: mdir 0CC Manufacturer: appl 0D0 Component reserved flags: 0 (0x00000000) 0D4 Component reserved flags mask: 0 (0x00000000) 0D8 Component type name: 0D9 List (45 bytes) 0D9 Header (8 bytes) 0D9 Size: 45 (0x0000002D) 0DD Name: ilst 0E1 Element (37 bytes) 0E1 Header (8 bytes) 0E1 Size: 37 (0x00000025) 0E5 Name: ﹖oo 0E9 Data - Encoded_Application (29 bytes) 0E9 Header (8 bytes) 0E9 Size: 29 (0x0000001D) 0ED Name: data 0F1 Kind: 1 (0x00000001) - UTF8 0F5 Language: 0 (0x00000000) 0F9 Value: Lavf58.29.100 106 --------------------------- 106 --- MPEG-4, filling --- 106 --------------------------- 106 ---------------------------- 106 --- MPEG-4, finished --- 106 ----------------------------
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章