使用FFmpeg将mp4转为ts(代码实现)
标签:
股票安卓相关it |
点击(此处)折叠或打开
-
ffmpeg
-i b.mp4 -codec copy -bsf h264_mp4toannexb a.ts
如果不使用-bsf h264_mp4toannexb参数,会提示错误,错误信息如下:
点击(此处)折叠或打开
-
ffmpeg
-i b.mp4 -codec copy a.ts
-
ffmpeg version N-65108-gf2855eb
Copyright
(c) 2000-2014 the FFmpeg developers -
built on Jul 31 2014 02:29:27 with gcc 4.4.7 (GCC) 20120313 (Red Hat 4.4.7-4)
-
configuration: --prefix=/usr/local --enable-gpl --enable-nonfree --enable-libfaac --enable-libfreetype --enable-libx264 --enable-libx265
-
libavutil 52. 93.100 / 52. 93.100
-
libavcodec 55. 71.100 / 55. 71.100
-
libavformat 55. 49.100 / 55. 49.100
-
libavdevice 55. 13.102 / 55. 13.102
-
libavfilter 4. 11.102 / 4. 11.102
-
libswscale 2. 6.100 / 2. 6.100
-
libswresample 0. 19.100 / 0. 19.100
-
libpostproc 52. 3.100 / 52. 3.100
-
Input #0,
mov,mp4,m4a,3gp,3g2,mj2, from 'b.mp4':
-
Metadata: -
major_brand : isom
-
minor_version : 512
-
compatible_brands: isomiso2avc1mp41
-
title : ????????
-
encoder : Lavf55.49.100
-
copyright : (C) 2004 HFD2B -
Duration: 00:04:09.44, start: 0.000000, bitrate: 568 kb/s -
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 592x336, 436 kb/s, 23.98 fps, 23.98 tbr, 785647.00 tbn, 47.95 tbc (default)
-
Metadata:
-
handler_name : VideoHandler
-
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
-
Metadata:
-
handler_name : SoundHandler
-
File
'a.ts' already exists. Overwrite ? [y/N] y
-
[adts @
0x2269660]
Using AVStream.codec.time_base as a timebase hint to the muxer is deprecated. Set AVStream.time_base instead. -
Output #0,
mpegts, to 'a.ts':
-
Metadata: -
major_brand : isom
-
minor_version : 512
-
compatible_brands: isomiso2avc1mp41
-
title : ????????
-
copyright : (C) 2004 HFD2B -
encoder : Lavf55.49.100
-
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p, 592x336, q=2-31, 436 kb/s, 23.98 fps, 90k tbn, 23.98 tbc (default)
-
Metadata:
-
handler_name : VideoHandler
-
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, 127 kb/s (default)
-
Metadata:
-
handler_name : SoundHandler
-
Stream mapping:
-
Stream #0:0 -> #0:0 (copy)
-
Stream #0:1 -> #0:1 (copy)
-
Press
[q] to stop, [?] for help
-
[mpegts @
0x22761a0]
H.264 bitstream malformed, no startcode found, use the h264_mp4toannexb bitstream filter (-bsf h264_mp4toannexb)
-
av_interleaved_write_frame():
Invalid argument -
frame=
1 fps=0.0 q=-1.0 Lsize= 1kB time=00:00:00.04 bitrate= 216.3kbits/s
-
video:1kB
audio:0kB
subtitle:0kB other
streams:0kB global
headers:0kB muxing
overhead:
unknown
- Conversion
从上面的提示纤细可以看到,提示了:
[mpegts @ 0x22761a0] H.264 bitstream malformed, no startcode found, use the h264_mp4toannexb bitstream filter (-bsf h264_mp4toannexb)
av_interleaved_write_frame(): Invalid argument
主要是因为使用了mp4中的h264编码,而h264有两种封装:
一种是annexb模式,传统模式,有startcode,SPS和PPS是在ES中;另一种是mp4模式,一般mp4、mkv、avi会没有startcode,SPS和PPS以及其它信息被封装在container中,每一个frame前面是这个frame的长度,很多解码器只支持annexb这种模式,因此需要将mp4做转换;在ffmpeg中用h264_mp4toannexb_filter可以做转换;所以需要使用-bsf h264_mp4toannexb来进行转换;
下面介绍一下代码实现:
代码实现主要分为三个步骤:
点击(此处)折叠或打开
-
1.
初始化filterav_bitstream_filter_init
-
2.
使用filter转换av_bitstream_filter_filter
-
3.
关闭filter av_bitstream_filter_close
其他与正常的转封装相同
点击(此处)折叠或打开
-
#include
<</span>stdio.h>
-
#include
<</span>stdlib.h>
-
#include
<</span>libavformat/avformat.h>
-
#include
<</span>libavutil/avutil.h>
-
-
#define FORMAT
"mpegts"
-
#define OUTPUT_FILE
"./fuck.ts"
-
#define INPUT_FILE
"./a.avi"
-
-
int
main(int argc, char *argv[])
-
{
-
AVPacket pkt; -
AVFormatContext *input_fmtctx = NULL;
-
AVFormatContext *output_fmtctx = NULL;
-
AVCodecContext *enc_ctx = NULL;
-
AVCodecContext *dec_ctx = NULL;
-
AVCodec *encoder = NULL;
-
AVBitStreamFilterContext * vbsf = NULL;
-
int ret = 0;
-
int i = 0;
-
int have_key = 0;
-
static int first_pkt = 1;
-
-
av_register_all();
-
-
if (avformat_open_input(&input_fmtctx, INPUT_FILE, NULL, NULL) <</span> 0) {
-
av_log(NULL, AV_LOG_ERROR, "Cannot open the file %s\n", "./a.mp4");
-
return -ENOENT;
-
}
-
-
if (avformat_find_stream_info(input_fmtctx,0) <</span> 0) {
-
av_log(NULL, AV_LOG_ERROR, "bbs.chinaffmpeg.com 孙悟空 Failed to retrieve input stream information\n");
-
return -EINVAL;
-
}
-
-
av_dump_format(input_fmtctx, NULL, INPUT_FILE, 0);
-
-
if (avformat_alloc_output_context2(&output_fmtctx, NULL, FORMAT, OUTPUT_FILE) <</span> 0) {
-
av_log(NULL, AV_LOG_ERROR, "Cannot open the file %s bbs.chinaffmpeg.com 孙悟空\n", OUTPUT_FILE);
-
return -ENOENT;
-
}
-
-
/* Process transcode parameters */
-
for (i = 0; i <</span> input_fmtctx->nb_streams; i++) {
-
AVStream *out_stream = NULL;
-
AVStream *in_stream = NULL;
-
-
in_stream = input_fmtctx->streams[i];
-
out_stream = avformat_new_stream(output_fmtctx, in_stream->codec->codec);
-
if (out_stream <</span> 0) {
-
av_log(NULL, AV_LOG_ERROR, "bbs.chinaffmpeg.com 孙悟空 Alloc new Stream error\n");
-
return -EINVAL;
-
}
-
-
avcodec_copy_context(output_fmtctx->streams[i]->codec, input_fmtctx->streams[i]->codec);
-
-
out_stream->codec->codec_tag = 0;
-
if (output_fmtctx->oformat->flags & AVFMT_GLOBALHEADER) {
-
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
}
-
}
-
-
vbsf = av_bitstream_filter_init("h264_mp4toannexb");
-
-
-
av_dump_format(output_fmtctx, NULL, OUTPUT_FILE, 1);
-
-
if (avio_open2(&output_fmtctx->pb, OUTPUT_FILE, AVIO_FLAG_WRITE, &output_fmtctx->interrupt_callback, NULL) <</span> 0) {
-
av_log(NULL, AV_LOG_ERROR, "cannot open the output file '%s' bbs.chinaffmpeg.com 孙悟空\n", "./fuck.m3u8");
-
return -ENOENT;
-
}
-
-
av_opt_set(output_fmtctx->priv_data, "hls_time", "10");
-
-
if ((ret = avformat_write_header(output_fmtctx, NULL)) <</span> 0) {
-
av_log(NULL, AV_LOG_ERROR, "bbs.chinaffmpeg.com 孙悟空 Cannot write the header for the file '%s' ret = %d\n", "fuck.ts", ret);
-
return -ENOENT;
-
}
-
-
while (1) {
-
AVStream *in_stream = NULL;
-
AVStream *out_stream = NULL;
-
-
ret = av_read_frame(input_fmtctx, &pkt);
-
if (ret <</span> 0) {
-
av_log(NULL, AV_LOG_ERROR, "read frame error %d bbs.chinaffmpeg.com 孙悟空\n", ret);
-
break;
-
}
-
-
if (pkt.pts == AV_NOPTS_VALUE && first_pkt) {
-
pkt.pts = pkt.dts;
-
first_pkt = 0;
-
}
-
-
in_stream = input_fmtctx->streams[pkt.stream_index];
-
out_stream = output_fmtctx->streams[pkt.stream_index];
-
-
pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
-
pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
-
pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
-
pkt.pos = -1;
-
-
if (pkt.stream_index == 0) {
-
-
AVPacket fpkt = pkt;
-
int a = av_bitstream_filter_filter(vbsf,
-
out_stream->codec, NULL, &fpkt.data, &fpkt.size,
-
pkt.data, pkt.size, pkt.flags & AV_PKT_FLAG_KEY);
-
pkt.data = fpkt.data;
-
pkt.size = fpkt.size;
-
-
}
-
-
ret = av_write_frame(output_fmtctx, &pkt);
-
if (ret <</span> 0) {
-
av_log(NULL, AV_LOG_ERROR, "bbs.chinaffmpeg.com 孙悟空 Muxing Error\n");
-
break;
-
}
-
-
av_free_packet(&pkt);
-
}
-
-
av_write_trailer(output_fmtctx);
-
avformat_close_input(&input_fmtctx);
-
avio_close(output_fmtctx->pb);
-
avformat_free_context(output_fmtctx);
-
av_bitstream_filter_close(vbsf);
-
vbsf = NULL;
-
-
return 0; - }
上海青大实训,最务实的上海计算机培训机构,我们的口号是:解决80,90后们与用人单位的“最后一公里”问题,我们将充分调研,根据市场用人需求的变动设置更加科学的科目,同时积极拓展就业渠道,为我们的学员提供最大的就业保障,上海电脑培训就到青大实训

加载中…