标签: libavformat

碎片化MP4 - 在浏览器中播放问题

我尝试用原始H264视频数据创建碎片化的MP4,这样我就可以在互联网浏览器的播放器中播放它了.我的目标是创建实时流媒体系统,媒体服务器将片段化的MP4片段发送到浏览器.服务器将缓冲来自RaspberryPi摄像头的输入数据,该摄像头将视频作为H264帧发送.然后它将复用该视频数据并使其可供客户端使用.浏览器将使用Media Source Extensions播放媒体数据(由服务器复制并通过websocket发送).

出于测试目的,我编写了以下代码片段(使用我在intenet中找到的许多示例):

使用avcodec的C++应用程序,它将原始H264视频复用到碎片MP4并将其保存到文件中:

#define READBUFSIZE 4096
#define IOBUFSIZE 4096
#define ERRMSGSIZE 128

#include <cstdint>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

extern "C"
{
    #include <libavformat/avformat.h>
    #include <libavutil/error.h>
    #include <libavutil/opt.h>
}

enum NalType : uint8_t
{
    //NALs containing stream metadata
    SEQ_PARAM_SET = 0x7,
    PIC_PARAM_SET = 0x8
};

std::vector<uint8_t> outputData;

int mediaMuxCallback(void *opaque, uint8_t *buf, int bufSize)
{
    outputData.insert(outputData.end(), buf, buf + bufSize);
    return bufSize;
}

std::string getAvErrorString(int errNr)
{
    char errMsg[ERRMSGSIZE];
    av_strerror(errNr, errMsg, ERRMSGSIZE);
    return std::string(errMsg);
} …
Run Code Online (Sandbox Code Playgroud)

c++ ffmpeg h.264 libavformat fmp4

6
推荐指数
1
解决办法
1044
查看次数

FFmpeg中按字节查找

我将感谢您对以下方面的建议。我正在开发一个基于FFmpeg的libavformat的视频转换器,我需要实现一个精确的查找API。首先,我开发了一个视频流索引器,它只保存每个数据包的呈现时间戳(PTS)。然后我的编码器使用这个索引来寻找视频文件。例如,在此操作之前,我将文件重新混合到 mp4 容器。对于内部没有正确索引或视频根本没有索引的视频,需要进行 Remux。我需要实现按字节查找,当然需要使用之前构建的索引。我尝试了很多方法来实现这一点,但没有成功。也许你知道如何在FFmpeg中实现按字节精确查找?此致。

ffmpeg fseek seek libavcodec libavformat

5
推荐指数
1
解决办法
2450
查看次数

使用ffmpeg库提取文本字幕

我正在编写一个使用 ffmpeg 的 libav* 库的 C 程序,并使用Dranger 的教程,我可以正确解码音频和视频。目前,我正在尝试提取字幕。我实际上不想按时解码它们并将它们显示在视频上,而是实际上从容器中提取字幕文本。

例如,在 cli 上,

ffmpeg -i video.mkv -map 0:4 -scodec copy out.ass
Run Code Online (Sandbox Code Playgroud)

会把屁股档案还给我。(由于某种原因,srts 只返回文本。)

我试过搞乱 AVSubtitle、avcodec_decode_subtitle2 等,但它们逐行返回字幕。我想要 srts 中的时间码、ass 中的标题信息等。我想要的只是混合到容器中的整个字幕文本文件。

ffmpeg libavcodec libav libavformat

5
推荐指数
1
解决办法
4977
查看次数

VLC:“avcodec 错误:视频延迟超过 5 秒”

我正在将 mpeg4 视频混合到 avi 容器。视频流约为 4fps,因此我设置AVCodecContext time_base为 1/4 ( formatContext->streams[0]->codec->time_base...) ,然后重新调整每个帧时间戳,因为原始时间戳以毫秒为单位。我将结果值分配给数据包ptsdts

当我用 VLC 播放此 avi 时,视频不流畅,并且反复收到以下消息:

avcodec 错误:视频延迟超过 5 秒 -> 丢帧(计算机太慢?)

上面的pts/dts计算有问题吗?

下表演示了时间戳如何重新缩放(原始->重新缩放)

stream: 0 1329471005111->1
stream: 0 1329471005348->2
stream: 0 1329471005588->3
stream: 0 1329471005828->4
stream: 0 1329471006068->5
stream: 0 1329471006308->6
stream: 0 1329471006551->7
stream: 0 1329471006788->8
stream: 0 1329471007028->9
stream: 0 1329471007268->10
stream: 0 1329471007508->11
stream: 0 1329471007748->12
stream: 0 1329471007988->13
stream: 0 1329471008228->14
stream: 0 1329471008468->15
Run Code Online (Sandbox Code Playgroud)

ffmpeg pts vlc libavformat

5
推荐指数
0
解决办法
1万
查看次数

如何使用libavformat用相同的编解码器连接2个视频文件(重新混合)?

我已经从CDN下载了flv格式的视频(视频H264和音频AAC),并将其重新混合为MP4格式。但是视频受到长度的限制。因此,我已经下载了每个部分的视频:从起点,第1点,第2点开始(通过使用url中的seek参数)。每一点的开始都比上一点的结束早。
使用av_read_framei扫描了所有部分,发现相交的数据包不仅具有相同的大小和顺序,而且它们的dts / pt彼此偏移恒定值。因此,要将视频与从点1开始的视频并置在一起,我必须执行以下操作:
1.在输出文件中创建输出标头
。2.复制起始视频中的所有非相交数据包。
3.通过将常量移动dts值,从点1开始的视频复制所有非相交的数据包

如何使用libav(不是ffmpeg)执行所有这些操作?我阅读了如何在不使用其他libav库的情况下使用libavformat。但libav它不工作,因为那里没有avformat_alloc_output_context2libavavconv.c对于像我这样的新手来说,源代码源也太复杂了,无法隔离与流复制操作相关的部分。
有人可以提供我为例:
-开放input_file1input_file2(仅当需要从通用教程标准程序不同)
-开放和写报头OUTPUT_FILE与同一容器格式和相同的视频和音频格式
-写数据包从input_file1OUTPUT_FILE直到与例如分组pos == XXX
-写入分组从input_file2OUTPUT_FILE由恒定值改变它们的DTS(或任何需要的话)
-写正确trailer

我之前在dts中计算时移。

ffmpeg muxer libav libavformat

5
推荐指数
1
解决办法
5321
查看次数

如何使用avcodec_decode_audio4解码AAC?

我将代码 avcodec_decode_audio3 更改为 avcodec_decode_audio4 并添加了帧处理。但现在我不能再解码 AAC 帧了。

为什么 avcodec_decode_audio4 返回-22无效参数)?按照下面的回答,这和AVContext中需要设置的参数有关系吗?

我不得不使用 avcodec_decode_audio4 因为我更新了我的 ffmpeg 然后出现以下错误:

[NULL @ 0xb14f020] Custom get_buffer() for use withavcodec_decode_audio3() detected. 
         Overriding with avcodec_default_get_buffer
[NULL @ 0xb14f020] Please port your application to avcodec_decode_audio4()
Run Code Online (Sandbox Code Playgroud)

根据avcodec_decode_audio4() 中的缓冲区错误,这是一个回归,除了回到 ffmpeg < 0.8 之外,还有其他解决方案吗?

使用 avcodec_decode_audio4 的解码器:

AVCodec *codec;
AVCodecContext *avCtx;
AVFrame * decoded_frame = NULL;
uint8_t *outbuf = static_cast<uint8_t *>(malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE));
AVPacket avPacket;

main(){
    av_register_all();
    codec = avcodec_find_decoder(CODEC_ID_AAC);

    //set parameters
    avCtx = avcodec_alloc_context3(codec);
    avCtx->channels = 1; …
Run Code Online (Sandbox Code Playgroud)

ffmpeg decoder libavcodec libav libavformat

5
推荐指数
1
解决办法
7545
查看次数

如何以编程方式使用 FFMpeg 修剪文件?(libavformat, avutils, ...)

我正在构建一个 iOS 应用程序,其中需要在后台重新编码和修剪视频。

我不能使用 iOS 库 (AVFoundation),因为它们依赖于 GPU,如果它是后台的,则没有应用程序可以访问 GPU。

由于这个问题,我切换到 FFMpeg 并编译它(与 libx264 一起)并将它集成到我的 iOS 应用程序中。

总结一下我需要的是:

  1. 修剪前 10 秒的视频
  2. 重新缩放视频

几周后——我经常用头撞墙——我设法:

  • 将视频容器拆分为流(解复用)
  • 将音频流复制到输出流中(无解码或编码)
  • 解码视频流,每帧运行必要的过滤器,编码每个结果帧并将其重新混合到输出流(我解码 h264,过滤它,将其重新编码回 h264)

如果我要通过命令行运行 ffmpeg,我会像这样运行它:

ffmpeg -i input.MOV -ss 0 -t 10  -vf scale=320:240 -c:v libx264 -preset ultrafast -c:a copy output.mkv
Run Code Online (Sandbox Code Playgroud)

我关心的是如何修剪视频?虽然我可以计算我编码/解码的视频帧的数量,并根据 FPS 决定何时停止,但我不能对音频做同样的事情,因为我只是对其进行解复用和重新复用。

理想情况下 - 在缩放视频之前 - 我会运行一个过程,通过将每个流(视频和音频)的 10 秒复制到一个新的视频容器中来修剪视频。

如何通过 AV 库实现这一目标?

ffmpeg video-processing libav ios libavformat

5
推荐指数
1
解决办法
452
查看次数

使用 LibAvFormat 转码视频以便在 iOS 设备上播放

我\xe2\x80\x99m 尝试使用 FFMpeg/LibAv 在我的 iOS 应用程序上对视频进行转码。\n我\xe2\x80\x99m 试图完成的是对视频进行转码,以便调整每个帧的大小并可能降低比特率为了在设备中节省宝贵的 MB。

\n\n

生成的视频必须可以在所有 iPhone5+ 设备上播放。

\n\n

阅读文档后我发现:

\n\n
    \n
  • 我不需要对音频流进行编码/解码 -> I\xe2\x80\x99ll 按原样复制到输出文件
  • \n
  • 我需要使用 h264 编解码器 (LibX264) 和 iOS 支持的配置文件(级别为 3.0 的基线配置文件 - https://trac.ffmpeg.org/wiki/Encode/H.264#Compatibility)对视频进行编码
  • \n
  • 我\xe2\x80\x99m还将图片格式设置为YUV平面,因为它\xe2\x80\x99s是iOS唯一支持的一种
  • \n
  • 为了测试 I\xe2\x80\x99m 根本不使用任何过滤器(I\xe2\x80\x99m 使用虚拟/直通),甚至尝试降低比特率,I\xe2\x80\x99m 只是尝试解码视频流并再次编码
  • \n
  • 大部分代码基于 FFMpeg 示例目录中的 transcoding.c 和filtering.c
  • \n
\n\n

从 FFMpeg 角度来看,我尝试使用 LibAv 实现的目标是:

\n\n
ffmpeg -i INPUT.MOV -c:v libx264 -preset ultrafast -profile:v baseline -level 3.0  -c:a copy output.MOV\n
Run Code Online (Sandbox Code Playgroud)\n\n

(生成的文件 - 可以在下面找到 - 如果它是由 FFMpeg 通过命令行生成的\xe2\x80\x99s,则可以在 QuickTime 上播放) …

ffmpeg h.264 libavcodec libav libavformat

5
推荐指数
0
解决办法
780
查看次数

FFmpeg(C/libav)VPX到mpeg2视频流无法在VLC中重现

我目前正在尝试将VPX(VP8/VP9)视频转码为mpeg2视频,并使用mpegts通过UDP进行流式传输.

我已经初始化了所有上下文和流,只要我将其流式传输到ffplay它就可以工作,如果我将流发送到VLC或其他播放器,接收器只显示第一帧而不执行任何其他操作.如果我通过命令行执行相同的操作,它可以完美地工作 - ffmpeg -re -i video.webm -an -f mpegts udp://127.0.0.1:8080

我的输出背景:

this->output_codec_ctx_->codec_type    = AVMEDIA_TYPE_VIDEO; // Set media type
this->output_codec_ctx_->pix_fmt       = AV_PIX_FMT_YUV420P; // Set stream pixel format
this->output_codec_ctx_->time_base.den = ceil(av_q2d(input_stream->r_frame_rate));     // Add the real video framerate. Eg.: 29.9
this->output_codec_ctx_->time_base.num = 1;                  // Numerator of the framerate. Eg.: num/29.9
this->output_codec_ctx_->width         = input_stream->codecpar->width;  // Video width
this->output_codec_ctx_->height        = input_stream->codecpar->height; // Video height
this->output_codec_ctx_->bit_rate      = 400000; // Video quality
this->output_codec_ctx_->gop_size      = 12;
this->output_codec_ctx_->max_b_frames  = 2;
this->output_codec_ctx_->framerate     = this->input_codec_ctx_->framerate;
this->output_codec_ctx_->sample_aspect_ratio     = this->input_codec_ctx_->sample_aspect_ratio;
Run Code Online (Sandbox Code Playgroud)

我的av_dump:

Output …
Run Code Online (Sandbox Code Playgroud)

c ffmpeg libavcodec libavformat

5
推荐指数
0
解决办法
124
查看次数

使用 FFmpeg 初始化用于混合 mkv 的输出文件

我是 ffmpeg 的第一次用户,我在初始化 mkv muxing 的输出文件时遇到了麻烦。我按照此页面中间的说明进行操作,但它不起作用。

当我调用 avformat_write_header() 函数时,它返回错误代码 -1094995529,这意味着:处理输入时发现无效数据。

当我将输出上下文分配为 mp4 格式(我在这两种情况下都使用 avformat_alloc_output_context2)时,我没有收到此错误,并且它成功地写入了标头。我试图分析这个例子的代码, 但我无法弄清楚问题是什么(我也尝试了不同的函数但没有结果)。

这是我的代码:

const char *filename = "c:\\Users\\MPM\\Desktop\\test.mkv";
AVFormatContext *mkvVideo = NULL;

int ret = 0;
ret = avformat_alloc_output_context2(&mkvVideo, av_guess_format("matroska", "c:\\Users\\MPM\\Desktop\\test.mkv", NULL), "mkv", filename);

std::cout << "\n avformat_alloc_output_context2: " << ret<<"\n";

AVStream* video_stream = avformat_new_stream(mkvVideo, NULL);

video_stream->time_base.den = 25;
video_stream->time_base.num = 1;
video_stream->id = mkvVideo->nb_streams - 1;

video_stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
video_stream->codecpar->codec_id = AV_CODEC_ID_H264;
video_stream->codecpar->bit_rate = 40000;
video_stream->codecpar->width = 1920;
video_stream->codecpar->height = 1080; …
Run Code Online (Sandbox Code Playgroud)

c++ video ffmpeg mkv libavformat

5
推荐指数
1
解决办法
838
查看次数

标签 统计

ffmpeg ×10

libavformat ×10

libav ×5

libavcodec ×5

c++ ×2

h.264 ×2

c ×1

decoder ×1

fmp4 ×1

fseek ×1

ios ×1

mkv ×1

muxer ×1

pts ×1

seek ×1

video ×1

video-processing ×1

vlc ×1