- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我使用 libavformat 将 h264 流和 aac 流封装成可播放的 mp4 文件。但是,封装成ts文件后,在Win10播放器中可以正常工作,但在vlc播放器中没有音频。封装时,打印音频流,但使用 fprobe 时,以 channel=0 打印音频流。这可能是什么原因?
而且h264源文件没有pts。所以我自己计算。
ffprobe print
ffmpeg print
这是我的代码。
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
static void log_packet(const AVFormatContext* fmt_ctx, const AVPacket* pkt, const char* tag)
{
AVRational* time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
printf("%s num=%d den=%d\n", tag, time_base->num, time_base->den);
printf("%s: pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
tag,
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
pkt->stream_index);
}
int main()
{
const char* in_filename_v = "test.h264";
const char* in_filename_a = "aoutput.aac";
const char* out_filename = "lol.ts";
//Video Input AVFormatContext
AVFormatContext* ifmt_ctx_v = NULL;
int ret = avformat_open_input(&ifmt_ctx_v, in_filename_v, 0, 0);
if (ret < 0)
{
fprintf(stderr, "Could not open input_v %s", in_filename_v);
return -1;
}
//Find Video Stream Info
ret = avformat_find_stream_info(ifmt_ctx_v, 0);
if (ret < 0)
{
fprintf(stderr, "Could not find input_v stream info");
return -1;
}
//Audio Input AVFormatContext
AVFormatContext* ifmt_ctx_a = NULL;
ret = avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0);
if (ret < 0)
{
fprintf(stderr, "Could not open input_a %s", in_filename_a);
return -1;
}
//Find Audio Stream Info
ret = avformat_find_stream_info(ifmt_ctx_a, 0);
if (ret < 0)
{
fprintf(stderr, "Could not find input_a stream info");
return -1;
}
printf("===========Input Information==========\n");
av_dump_format(ifmt_ctx_v, 0, in_filename_v, 0);
av_dump_format(ifmt_ctx_a, 0, in_filename_a, 0);
printf("======================================\n");
//Output AVFormatContext
AVFormatContext* ofmt_ctx = NULL;
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
if (!ofmt_ctx)
{
fprintf(stderr, "cannot alloc OutputFromat context!");
ret = AVERROR_UNKNOWN;
return -1;
}
AVOutputFormat* ofmt = ofmt_ctx->oformat;
//Alloc AVSTREAM
int istream_index_v = 0, istream_index_a = 0, ostream_index_v = 0, ostream_index_a = 0;
for (int i = 0; i < ifmt_ctx_v->nb_streams; i++)
{
AVStream* outstream;
AVStream* in_stream = ifmt_ctx_v->streams[i];
AVCodecParameters* in_codecpar = in_stream->codecpar;
if (in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
continue;
outstream = avformat_new_stream(ofmt_ctx, NULL);
if (!outstream)
{
fprintf(stderr, "Failed allocating output stream\n");
return -1;
}
ret = avcodec_parameters_copy(outstream->codecpar, in_codecpar);
if (ret < 0)
{
fprintf(stderr, "Failed to copy codec parameters\n");
return -1;
}
outstream->codecpar->codec_tag = 0;
// Remeber video stream id
istream_index_v = i;
ostream_index_v = 0;
break;
}
for (int i = 0; i < ifmt_ctx_a->nb_streams; i++)
{
AVStream* outstream;
AVStream* in_stream = ifmt_ctx_a->streams[i];
AVCodecParameters* in_codecpar = in_stream->codecpar;
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
continue;
outstream = avformat_new_stream(ofmt_ctx, NULL);
if (!outstream)
{
fprintf(stderr, "Failed allocating output stream\n");
return -1;
}
ret = avcodec_parameters_copy(outstream->codecpar, in_codecpar);
if (ret < 0)
{
fprintf(stderr, "Failed to copy codec parameters\n");
return -1;
}
outstream->codecpar->codec_tag = 0;
// Remeber audio stream id
istream_index_a = i;
ostream_index_a = 1;
break;
}
printf("===========Output Information==========\n");
av_dump_format(ofmt_ctx, 0, out_filename, 1);
printf("======================================\n");
if (!(ofmt->flags & AVFMT_NOFILE))
{
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
if (ret < 0)
{
fprintf(stderr, "Could not open output file '%s'", out_filename);
return -1;
}
}
//Write file header
ret = avformat_write_header(ofmt_ctx, NULL);
if (ret < 0) {
fprintf(stderr, "Error occurred when opening output file\n");
return -1;
}
//read and write packet
AVPacket* pkt = av_packet_alloc();
if (!pkt)
{
fprintf(stderr, "Could not allocate AVPacket\n");
return -1;
}
while (1)
{
AVStream* in_stream, * outstream;
ret = av_read_frame(ifmt_ctx_v, pkt);
if (ret < 0)
break;
in_stream = ifmt_ctx_v->streams[pkt->stream_index];
if (pkt->stream_index != istream_index_v)
{
av_packet_unref(pkt);
continue;
}
pkt->stream_index = ostream_index_v;
outstream = ofmt_ctx->streams[pkt->stream_index];
// in log info
log_packet(ifmt_ctx_v, pkt, "in");
if (pkt->pts == AV_NOPTS_VALUE)
{
AVRational time_base1 = in_stream->time_base;
//
int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(in_stream->r_frame_rate);
static int frame_index = 0;
pkt->pts = (double)(frame_index * calc_duration) / (double)(av_q2d(time_base1) * AV_TIME_BASE);
pkt->dts = pkt->pts;
pkt->duration = (double)calc_duration / (double)(av_q2d(time_base1) * AV_TIME_BASE);
frame_index++;
}
// duration between two frames(us)
av_packet_rescale_ts(pkt, in_stream->time_base, outstream->time_base);
pkt->pos = -1;
// out log info
log_packet(ofmt_ctx, pkt, "out");
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
if (ret < 0)
{
fprintf(stderr, "Error muxing packet\n");
break;
}
}
while (1)
{
AVStream* in_stream, * outstream;
ret = av_read_frame(ifmt_ctx_a, pkt);
if (ret < 0)
break;
in_stream = ifmt_ctx_a->streams[pkt->stream_index];
if (pkt->stream_index != istream_index_a)
{
av_packet_unref(pkt);
continue;
}
if (pkt->pts == AV_NOPTS_VALUE)
{
AVRational time_base1 = in_stream->time_base;
// duration between two frames(us)
int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(in_stream->r_frame_rate);
static int frame_index = 0;
pkt->pts = (double)(frame_index * calc_duration) / (double)(av_q2d(time_base1) * AV_TIME_BASE);
pkt->dts = pkt->pts;
pkt->duration = (double)calc_duration / (double)(av_q2d(time_base1) * AV_TIME_BASE);
frame_index++;
}
// in log info
log_packet(ifmt_ctx_a, pkt, "in");
pkt->stream_index = ostream_index_a;
outstream = ofmt_ctx->streams[pkt->stream_index];
//change timestamp
av_packet_rescale_ts(pkt, in_stream->time_base, outstream->time_base);
pkt->pos = -1;
// out log info
log_packet(ofmt_ctx, pkt, "out");
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
if (ret < 0)
{
fprintf(stderr, "Error muxing packet\n");
break;
}
}
//write file trailer
av_write_trailer(ofmt_ctx);
printf("===========Output Information==========\n");
av_dump_format(ofmt_ctx, 0, out_filename, 1);
printf("======================================\n");
}
DVB Insepctor video
最佳答案
感谢@aergistal。
av_interleaved_write_frame
有缓冲限制。我#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#define EXTRAL 1
static void log_packet(const AVFormatContext* fmt_ctx, const AVPacket* pkt, const char* tag)
{
AVRational* time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
FILE* fp = fopen("fflog.log", "a+");
char buf[200];
sprintf(buf, "%s num=%d den=%d\n", tag, time_base->num, time_base->den);
for (int i = 0; *(buf + i) != '\0'; i++)
{
fwrite(buf + i, 1, 1, fp);
}
sprintf(buf, "%s: pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
tag,
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
pkt->stream_index);
for (int i = 0; *(buf + i) != '\0'; i++)
{
fwrite(buf + i, 1, 1, fp);
}
fclose(fp);
}
int main()
{
const char* in_filename_v = "test.h264";
const char* in_filename_a = "aoutput.aac";
const char* out_filename = "lol.ts";
AVFormatContext* ifmt_ctx_v = NULL;
int ret = avformat_open_input(&ifmt_ctx_v, in_filename_v, 0, 0);
if (ret < 0)
{
fprintf(stderr, "Could not open input_v %s", in_filename_v);
return -1;
}
ret = avformat_find_stream_info(ifmt_ctx_v, 0);
if (ret < 0)
{
fprintf(stderr, "Could not find input_v stream info");
return -1;
}
AVFormatContext* ifmt_ctx_a = NULL;
ret = avformat_open_input(&ifmt_ctx_a, in_filename_a, 0, 0);
if (ret < 0)
{
fprintf(stderr, "Could not open input_a %s", in_filename_a);
return -1;
}
ret = avformat_find_stream_info(ifmt_ctx_a, 0);
if (ret < 0)
{
fprintf(stderr, "Could not find input_a stream info");
return -1;
}
#if EXTRAL
printf("===========Input Information==========\n");
av_dump_format(ifmt_ctx_v, 0, in_filename_v, 0);
av_dump_format(ifmt_ctx_a, 0, in_filename_a, 0);
printf("======================================\n");
#endif
AVFormatContext* ofmt_ctx = NULL;
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
if (!ofmt_ctx)
{
fprintf(stderr, "cannot alloc OutputFromat context!");
ret = AVERROR_UNKNOWN;
return -1;
}
AVOutputFormat* ofmt = ofmt_ctx->oformat;
int istream_index_v = 0, istream_index_a = 0, ostream_index_v = 0, ostream_index_a = 0;
for (int i = 0; i < ifmt_ctx_v->nb_streams; i++)
{
AVStream* outstream;
AVStream* in_stream = ifmt_ctx_v->streams[i];
AVCodecParameters* in_codecpar = in_stream->codecpar;
if (in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
continue;
outstream = avformat_new_stream(ofmt_ctx, NULL);
if (!outstream)
{
fprintf(stderr, "Failed allocating output stream\n");
return -1;
}
ret = avcodec_parameters_copy(outstream->codecpar, in_codecpar);
if (ret < 0)
{
fprintf(stderr, "Failed to copy codec parameters\n");
return -1;
}
outstream->codecpar->codec_tag = 0;
istream_index_v = i;
ostream_index_v = 0;
break;
}
for (int i = 0; i < ifmt_ctx_a->nb_streams; i++)
{
AVStream* outstream;
AVStream* in_stream = ifmt_ctx_a->streams[i];
AVCodecParameters* in_codecpar = in_stream->codecpar;
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
continue;
outstream = avformat_new_stream(ofmt_ctx, NULL);
if (!outstream)
{
fprintf(stderr, "Failed allocating output stream\n");
return -1;
}
ret = avcodec_parameters_copy(outstream->codecpar, in_codecpar);
if (ret < 0)
{
fprintf(stderr, "Failed to copy codec parameters\n");
return -1;
}
outstream->codecpar->codec_tag = 0;
istream_index_a = i;
ostream_index_a = 1;
break;
}
#if EXTRAL
printf("===========Output Information==========\n");
av_dump_format(ofmt_ctx, 0, out_filename, 1);
printf("======================================\n");
#endif
if (!(ofmt->flags & AVFMT_NOFILE))
{
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
if (ret < 0)
{
fprintf(stderr, "Could not open output file '%s'", out_filename);
return -1;
}
}
ret = avformat_write_header(ofmt_ctx, NULL);
if (ret < 0) {
fprintf(stderr, "Error occurred when opening output file\n");
return -1;
}
AVPacket* pkt = av_packet_alloc();
if (!pkt)
{
fprintf(stderr, "Could not allocate AVPacket\n");
return -1;
}
int64_t pts_v = 0, pts_a = 0;
while (1)
{
if (av_compare_ts(pts_a, ifmt_ctx_a->streams[istream_index_a]->time_base, pts_v, ifmt_ctx_v->streams[istream_index_v]->time_base) <= 0)
{
AVStream* in_stream, * outstream;
ret = av_read_frame(ifmt_ctx_a, pkt);
if (ret < 0)
break;
in_stream = ifmt_ctx_a->streams[pkt->stream_index];
if (pkt->stream_index != istream_index_a)
{
av_packet_unref(pkt);
continue;
}
if (pkt->pts == AV_NOPTS_VALUE)
{
AVRational time_base1 = in_stream->time_base;
int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(in_stream->r_frame_rate);
static int frame_index = 0;
pkt->pts = (double)(frame_index * calc_duration) / (double)(av_q2d(time_base1) * AV_TIME_BASE);
pkt->dts = pkt->pts;
pkt->duration = (double)calc_duration / (double)(av_q2d(time_base1) * AV_TIME_BASE);
frame_index++;
}
pts_a = pkt->pts;
// in log info
log_packet(ifmt_ctx_a, pkt, "in audio");
pkt->stream_index = ostream_index_a;
outstream = ofmt_ctx->streams[pkt->stream_index];
av_packet_rescale_ts(pkt, in_stream->time_base, outstream->time_base);
pkt->pos = -1;
// out log info
log_packet(ofmt_ctx, pkt, "out audio");
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
if (ret < 0)
{
fprintf(stderr, "Error muxing packet\n");
return -1;
}
}
else
{
AVStream* in_stream, * outstream;
ret = av_read_frame(ifmt_ctx_v, pkt);
if (ret < 0)
break;
in_stream = ifmt_ctx_v->streams[pkt->stream_index];
if (pkt->stream_index != istream_index_v)
{
av_packet_unref(pkt);
continue;
}
pkt->stream_index = ostream_index_v;
outstream = ofmt_ctx->streams[pkt->stream_index];
if (pkt->pts == AV_NOPTS_VALUE)
{
AVRational time_base1 = in_stream->time_base;
int64_t calc_duration = (double)AV_TIME_BASE / av_q2d(in_stream->r_frame_rate);
static int frame_index = 0;
pkt->pts = (double)(frame_index * calc_duration) / (double)(av_q2d(time_base1) * AV_TIME_BASE);
pkt->dts = pkt->pts;
pkt->duration = (double)calc_duration / (double)(av_q2d(time_base1) * AV_TIME_BASE);
frame_index++;
}
pts_v = pkt->pts;
// in log info
log_packet(ifmt_ctx_v, pkt, "in video");
av_packet_rescale_ts(pkt, in_stream->time_base, outstream->time_base);
pkt->pos = -1;
// out log info
log_packet(ofmt_ctx, pkt, "out video");
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
if (ret < 0)
{
fprintf(stderr, "Error muxing packet\n");
return -1;
}
}
}
ret = av_write_trailer(ofmt_ctx);
if (ret < 0)
{
fprintf(stderr, "Error av_write_trailer\n");
}
#if EXTRAL
printf("===========Output Information==========\n");
av_dump_format(ofmt_ctx, 0, out_filename, 1);
printf("======================================\n");
#endif
av_packet_free(&pkt);
avformat_close_input(&ifmt_ctx_v);
avformat_close_input(&ifmt_ctx_a);
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
avio_closep(&ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
return 0;
}
关于ffmpeg - 使用 ffmpeg muxer 到 MPEG2TS ,音频流无法在 vlc 播放器中播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70119438/
我正在尝试将音频添加到由以下开源项目创建的视频 特别是https://github.com/madisp/trails/blob/master/app/src/main/java/com/madisp
我遇到了媒体混合器的问题。为什么我的应用程序会崩溃?什么是解决方案? java.lang.IllegalStateException: Failed to stop the muxer at
有谁知道如何使用三通伪复用器 ffmpeg 通过 c++ 代码 .请指导这样做。 我正在努力获取多路复用传输流 (ts) 数据的多个输出。我能够在 ts 中复用 aac 和 h264。但我必须在多个输
ffmpeg hls muxer 可以选择设置主播放列表,但创建的播放列表缺少重要的编解码器信息。 例子: ffmpeg -hide_banner -i -c copy -f hls -master
你们中有人了解 weblogic.socket.Muxer 在 WebLogic 8.1 中的用途吗? 我经常在线程转储中看到与此类似的堆栈跟踪: "ExecuteThread: '0' for qu
我正在尝试使用 libavformat 多路复用器“hlsenc.c”......查看多路复用器的代码,看起来多路复用器通过 AVOption 机制支持参数......例如,hlsenc.c 多路复用
所以我试图为一个充满 gif 的文件夹添加水印,但我收到一条错误消息,说我当时只能使用一个 GIF 流,有没有办法绕过这个问题? @echo off setlocal for %%G in ("%~d
我尝试使用 bitstream filter 将元数据附加到段复用器没有成功,请告诉我怎么做? 最佳答案 MXF 复用器依赖于从每个 H.264 KF 数据包中提取额外数据,当通过段用户调用它时,这些
我正在使用 mime 类型为“video/avc”的 MediaCodec 对 Camera 预览数据进行编码,并将编码后的数据(仅视频,无音频)传递给 MediaMuxer。混合器似乎运行良好并创建
我想在 1 个 ffmpeg 进程中流式传输到 youtube 和 twitter 我红了这个https://trac.ffmpeg.org/wiki/Creating%20multiple%20ou
当将 mpegts 管道传输到 ffmpeg 时,它应该将其转换为 mp4 并将管道传输到 stdout,ffmpeg 说:“muxer 不支持不可搜索的输出”。 经过大量研究后,我得出的结论是,由于
我正在尝试在Android 4.2.2 上构建一个视频录制系统,我已经完成了编码部分,它使用的是OMX。现在我正在处理 Muxer 部分,因为如果我使用 FFMpeg 视频的码流可能会有些不同,所以我
我在停止 MediaMuxer 时遇到问题。 很多人都关注了 fadden's example一直以来,除了我使用的是音频,所以我还不能 100% 确定音频和视频轨道是否对齐。这可能是问题所在。 当我
我们最近开始体验使用 weblogic.Deployer 实用程序在 Weblogic 12c 中进行部署。我们可以很好地部署 EAR,但每当我们尝试在托管服务器仍在运行的情况下取消部署该应用程序时,
Media Muxer Media Muxer 不适用于 Lolipop 在 Android Emulator Api 22 (Lolipop) 上测试 这是我的混合音频和视频文件的代码 public
ffmpeg documentation说我们可以使用 dash muxer 来创建 dash 段和 list 文件,只需要一个命令,比如: ffmpeg -re -i -map 0 -map 0
这真的是我的应用程序中的一个阻塞问题吗? weblogic.socket.DevPollSocketMuxer.processSockets(DevPollSocketMuxer.java:92) 在
我有一个应用程序可以在存储在缓冲区中的 LPCM 中记录原始音频数据。我想将数据封装在传输流中,并通过 UDP 将该传输流发送到另一台主机上的流分段器(根据 HTTP Live Streaming 规
我使用 libavformat 将 h264 流和 aac 流封装成可播放的 mp4 文件。但是,封装成ts文件后,在Win10播放器中可以正常工作,但在vlc播放器中没有音频。封装时,打印音频流,但
我做了一个简单的图表来编写 MKV 文件。但我不想使用文件编写器。我想使用 SampleGabber 并使用简单的程序获取流。问题是我从 Matroska muxer 以外的任何地方获取数据!(我该怎
我是一名优秀的程序员,十分优秀!