- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在使用 libav
将视频的音频流提取到原始 PCM 文件中。
此代码适用于 mp3,但当我尝试使用 mp4 视频时,Audacity 上导入的原始格式显示奇怪的 0 到 -1 之间的规则下降线。
这是我的实现。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
int decode_raw(AVFormatContext *format_ctx)
{
AVCodec *codec = NULL;
AVCodecContext* codec_ctx = NULL;
AVFrame* frame = NULL;
AVPacket packet;
int stream_idx = av_find_best_stream(format_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
int res;
if (stream_idx < 0) {
printf("Could not find stream.\n");
return (1);
}
if ((codec_ctx = avcodec_alloc_context3(codec)) == NULL) {
printf("Could not allocate codec context.\n");
return (1);
}
if (avcodec_parameters_to_context(codec_ctx, format_ctx->streams[stream_idx]->codecpar) < 0) {
printf("Could not setup codec context parameters.\n");
return (1);
}
// Explicitly request non planar data.
codec_ctx->request_sample_fmt = av_get_packed_sample_fmt(codec_ctx->sample_fmt);
if (avcodec_open2(codec_ctx, codec, NULL) != 0) {
printf("Could not open codec.\n");
return (1);
}
if ((frame = av_frame_alloc()) == NULL) {
printf("Could not alloc frame.\n");
return (1);
}
av_init_packet(&packet);
int fd = open("raw", O_CREAT | O_WRONLY | O_TRUNC);
// Decode frames.
while ((res = av_read_frame(format_ctx, &packet)) == 0) {
// Does the packet belong to the correct stream?
if (packet.stream_index != stream_idx) {
av_packet_unref(&packet);
continue;
}
// We have a valid packet => send it to the decoder.
if ((res = avcodec_send_packet(codec_ctx, &packet)) != 0) {
printf("Failed to send packet: %d.\n", res);
break;
}
av_packet_unref(&packet);
res = avcodec_receive_frame(codec_ctx, frame);
if (res == AVERROR(EAGAIN) || res == AVERROR_EOF)
break;
else if (res < 0) {
printf("Failed to decode packet: %d.\n", res);
return (1);
}
write(fd, frame->extended_data[0], frame->linesize[0]);
}
close(fd);
av_frame_free(&frame);
avcodec_close(codec_ctx);
avcodec_free_context(&codec_ctx);
return (0);
}
int main(int argc, char **argv)
{
AVFormatContext *av_format_ctx = NULL;
if (argc != 2) {
printf("./streamer [file]\n");
return (1);
}
if (avformat_open_input(&av_format_ctx, argv[1], NULL, NULL) != 0) {
printf("Could not open input file.");
return (1);
}
if (avformat_find_stream_info(av_format_ctx, NULL) != 0) {
printf("Could not find stream information.");
return (1);
}
decode_raw(av_format_ctx);
avformat_close_input(&av_format_ctx);
return (0);
}
ffmpeg -i video.mp4 -f f32le output.raw
(我的代码输出AV_SAMPLE_FMT_FLT
)比较两个文件。我 hexdump 了这两个文件并找到了这个。
// 96 1f 03 3f - 22 03 0c 3f
// Doesn't exist in the output of my program?
5581a0 7c ad 6f bc 96 1f 03 3f 4f 01 25 3e 22 03 0c 3f |.o....?O.%>"..? // ffmpeg
5580d0 7c ad 6f bc 4f 01 25 3e 3a d2 89 3e 7c d7 9a 3e |.o.O.%>:..>|..> // my implementation
在经历了无数次令人失望的经历之后,AAC 音频流在解码后似乎已损坏。但是,ffmpeg 的原始 PCM 输出适用于 MP4。
我尝试使用 swr_convert
对音频帧重新采样,但它的文档太少,我遇到了很多问题。
最佳答案
打印音频流信息后。我注意到 AAC(mp4 文件的音频编解码器)不支持非平面格式(打包)。
// Explicitly request non planar data.
codec_ctx->request_sample_fmt = av_get_packed_sample_fmt(codec_ctx->sample_fmt);
由于不支持请求的格式,mp4 文件的音频流被解码为平面,这与 mp3 文件不同。
---------
Codec: MP3 (MPEG audio layer 3)
Supported sample formats: fltp, flt # MP3 support non planar
---------
Stream: 0
Sample Format: fltp
Sample Rate: 48000
Sample Size: 4
Channels: 2
Planar Output: yes
---------
Codec: AAC (Advanced Audio Coding)
Supported sample formats: fltp # AAC doesn't support non planar
---------
Stream: 1
Sample Format: fltp
Sample Rate: 44100
Sample Size: 4
Channels: 2
Planar Output: yes
为了解决这个问题,我删除了上面的行以保持流平面。我还必须更改我在文件中的写入方式。
由于格式是平面 LR, LR, LR
而不是打包 LL LL RR RR
,我不得不手动交替写入每个 channel 。
因为逐字节写入需要很长时间,所以我写了一个函数,先写入缓冲区,然后再将缓冲区写入文件。
void audio_pack_stream(AVCodecContext* codec_ctx, AVFrame *frame, uint8_t *dst, int *size)
{
int bytes = av_get_bytes_per_sample(codec_ctx->sample_fmt);
int actual = 0;
for (int i = 0; i < frame->nb_samples; i++) {
for(int j = 0; j < codec_ctx->channels; j++)
for (int k = 0; k < bytes; k++)
dst[*size++] = frame->extended_data[j][actual + k];
actual += bytes;
}
return (size);
}
// After avcodec_receive_frame
uint8_t output[4096 * 8];
int size;
audio_pack_stream(codec_ctx, frame, output, &size);
write(fd, output, size);
关于c - 使用 Libav 对视频的原始音频解码被切碎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62539816/
来自Linux背景。我只是想知道在 OSX 上安装 avprobe 的最佳方法是什么? 我尝试安装 libav:http://libav.org/download.html但这似乎使用了avconf。
如何在FFmpeg C API中编码之前为帧计算正确的PTS值? 为了进行编码,我使用了avcodec_encode_video2函数,然后通过av_interleaved_write_frame编写
使用 libav 保存视频中的帧。 问题是,如果你多次调用 decode 函数,然后调用 2nd,然后就没有正确处理。 第一次这样的结论(一切正常): [swscaler @ 0x8b48510]No
我正在尝试制作一个简单的 av 播放器,在某些情况下,我可以正确获取如下值: checking /media/timecapsule/Music/02 Baawre.mp3 [mp3 @ 0x7f06
我在OS X Mavericks上没有安装libav的运气。我已经尝试了一切。 我正在遵循此指南:http://earthwithsun.com/questions/568464/install-la
尝试使用 ffmpeg 打开网络摄像头(ffplay -f video4linux2/dev/video0 有效 pFormatCtx = NULL; av_register_all(
我使用下面的命令来转换文件 ./avconv -i inputFile -vcodec libx264 -trellis 2 -crf 23 -tune psnr -vf Crop='trunc(iw
我试图通过使用代码将 MP2 文件转换为原始 PCM 来获得与 ffmpeg/avconv 相同的输出。我使用了 the tutorial included in the FFmpeg/Libav d
我正在关注 ffmpeg 文档中的音频编码示例:https://www.ffmpeg.org/doxygen/0.6/api-example_8c-source.html 但我想解码 .wav 文件,
我正在尝试使用 libav(ffmpeg) 创建带有 MJPEG 视频负载的 RTP 流示例代码非常简单,适用于 MPEG1我看到 MJPEG 中的编码有效,但是当我需要发送 mjpeg 时帧 RTP
有没有办法使用 libav/avconv 来复制 FFMPEG 中瓦片过滤器的效果? 我正在尝试为每十秒的视频输入创建一个从左到右的图像 strip 。 我的计划是首先生成图像,然后创建图像条。最好我
我正在尝试使用 libav 在我的应用程序中删除视频的某些部分,例如在长度为 00:08:00 的视频中,我尝试删除帧 100-250 和 400-500(仅作为示例)。 我写了这段代码来复制 AVP
我有一个能够同时生成 5 个 mpeg 传输流的程序。每个流都有自己的上下文,并在独立的线程中完成。当只有一个流处于事件状态时,一切都很好。一旦我激活另一个流,我的帧速率就会大大下降。两个流仍然可以正
我有一系列编码数据包、H.264 视频和 AAC 音频。当它们出现时,我正在使用 av_write_frame 将它们写入视频文件。 连续给定以下情况 10秒视频,然后 10 秒的视频和音频,然后 1
我看到了这个答案,Libav (ffmpeg) copying decoded video timestamps to encoder 但我仍然不明白为什么我们需要流时基和编解码器时基。目前我正在尝试
我正在尝试学习使用 libav。我遵循了 dranger.com 上的第一个教程,但有一次我有点困惑。 // Write pixel data for(y=0; ydata[0]+y*pFrame->
我有一个从我的手机以纵向模式拍摄的视频。以下是有关视频的转储信息: Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.MOV': Metadata: maj
我有一个带有卡住(热)像素的视频,我想修复它,比如说用相邻像素的平均值替换像素。我在 Ubuntu 上,所以我想使用 libav/ffmpeg,但我真的不知道该怎么做。谁能提供一个简单的解决方案? 最
这个问题在这里已经有了答案: FFMPEG (libx264) "height not divisible by 2" (7 个回答) 5年前关闭。 我需要批量处理一堆视频以将它们的高度缩放到 240
我目前正在使用 libav 将视频的音频流提取到原始 PCM 文件中。 此代码适用于 mp3,但当我尝试使用 mp4 视频时,Audacity 上导入的原始格式显示奇怪的 0 到 -1 之间的规则下降
我是一名优秀的程序员,十分优秀!