我试图使用ffmpeg库在视频中寻找给定的帧.我知道有av_seek_frame()功能,但建议使用它avformat_seek_file().这里提到类似的东西.
我知道avformat_seek_file()不能总是把你带到你想要的确切框架,但这对我来说没问题.我只是想跳到最近的关键帧.所以我打开视频,找到视频流并像这样调用它:
avformat_seek_file( formatContext, streamId, 0, frameNumber, frameNumber, AVSEEK_FLAG_FRAME )
Run Code Online (Sandbox Code Playgroud)
它总是返回0,所以我理解为正确完成.但是,它不能正常工作.我检查字节位置像这里之前和之后调用avformat_seek_file().实际上它会改变,但每当我试图放置不同的目标帧数时,它总会以相同的方式改变!我的意思是,即使使用不同的frameNumber值,此调用后的字节位置也始终相同.显然,我做错了但我不知道到底是什么.我不知道它是否重要,但我正在使用.h264文件.我尝试了不同的标志,不同的文件,使用时间戳而不是帧,前后刷新缓冲等等,但它对我不起作用.如果有人能告诉我它有什么问题,我将非常感激.
人们,祝你有美好的一天!
我正在编写一个Windows应用程序,它将捕获屏幕并通过rtmp(用于广播)将流发送到Wowza服务器.我的应用程序使用ffmpeg和Qt.我使用WinApi捕获屏幕,将缓冲区转换为YUV444(因为它最简单)并按照文件decode_encoding.c(来自FFmpeg示例)中的描述对帧进行编码:
///////////////////////////
//Encoder initialization
///////////////////////////
avcodec_register_all();
codec=avcodec_find_encoder(AV_CODEC_ID_H264);
c = avcodec_alloc_context3(codec);
c->width=scr_width;
c->height=scr_height;
c->bit_rate = 400000;
int base_num=1;
int base_den=1;//for one frame per second
c->time_base= (AVRational){base_num,base_den};
c->gop_size = 10;
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV444P;
av_opt_set(c->priv_data, "preset", "slow", 0);
frame = avcodec_alloc_frame();
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
for(int counter=0;counter<10;counter++)
{
///////////////////////////
//Capturing Screen
///////////////////////////
GetCapScr(shotbuf,scr_width,scr_height);//result: shotbuf is filled by screendata from HBITMAP
///////////////////////////
//Convert buffer to YUV444 (standard formula)
//It's handmade function because of problems with prepare buffer …Run Code Online (Sandbox Code Playgroud) 我试图在ffmpeg/libav中将RGB帧转换为YUV420P格式.以下是转换代码以及转换前后的图像.转换后的图像会丢失所有颜色信息,并且尺度也会发生显着变化.有谁知道如何处理这个?我是ffmpeg/libav的新手!
// Did we get a video frame?
if(frameFinished)
{
i++;
sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data,
pFrame->linesize, 0, pCodecCtx->height,
pFrameRGB->data, pFrameRGB->linesize);
//==============================================================
AVFrame *pFrameYUV = avcodec_alloc_frame();
// Determine required buffer size and allocate buffer
int numBytes2 = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
pCodecCtx->height);
uint8_t *buffer = (uint8_t *)av_malloc(numBytes2*sizeof(uint8_t));
avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_RGB24,
pCodecCtx->width, pCodecCtx->height);
rgb_to_yuv_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
PIX_FMT_RGB24,
pCodecCtx->width,pCodecCtx->height,
PIX_FMT_RGB24,
SWS_BICUBIC, NULL,NULL,NULL);
sws_scale(rgb_to_yuv_ctx, pFrameRGB->data, pFrameRGB->linesize, 0,
pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
sws_freeContext(rgb_to_yuv_ctx);
SaveFrame(pFrameYUV, pCodecCtx->width, pCodecCtx->height, i);
av_free(buffer);
av_free(pFrameYUV);
}
Run Code Online (Sandbox Code Playgroud)


我正在研究ffmpeg将其核心功能用作其一部分的python项目。从本质上讲ffmpeg,我使用的功能归结为以下两个命令:
ffmpeg -i udp://<address:port> -qscale:v 2 -vf "fps=30" sttest%04d.jpg
ffmpeg -i udp://<address:port> -map data-re -codec copy -f data out.bin
Run Code Online (Sandbox Code Playgroud)
很简单的东西。
我正在尝试创建一个自包含的程序(使用上述ffmpeg功能),可以轻松地将其安装在任何特定系统上,而无需依赖具有必要依赖项的系统,因为我希望将这些依赖项与程序本身打包在一起。
考虑到这一点,最好在程序中使用这些libav*库来执行此功能吗?还是ffmpy使用ffmpeg命令行工具的包装器()更好?我目前对每种弊端的想法是,使用库可能是最佳实践,但是要学会使用它们似乎很复杂(并且可能会学习C,这是我从未学过的C)。做我上面提到的两个基本的事情。总体而言,这些库对我来说有点黑匣子,并且没有太多的文档。但是,使用包装器的问题ffmpeg在于它本质上依赖于调用子进程,这似乎有些草率。尽管我不确定为什么我会如此强烈地反对子流程。
为了确定给定文件的视频持续时间,我使用 libavformat。我的程序如下所示:
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
int main (int argc, char **argv) {
AVFormatContext *fmt_ctx = NULL;
int ret;
if (argc != 2) {
printf("usage: %s <input_file>\n", argv[0]);
return 1;
}
av_register_all();
if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
return ret;
int64_t duration = fmt_ctx->duration;
int hours, mins, secs;
secs = duration / AV_TIME_BASE;
mins = secs / 60;
secs %= 60;
hours = mins / 60;
mins %= 60;
printf("Duration: %02d:%02d:%02d\n", hours, mins, secs);
avformat_free_context(fmt_ctx);
return 0; …Run Code Online (Sandbox Code Playgroud) libavformat ×5
ffmpeg ×4
libavcodec ×3
c++ ×2
libav ×2
g++ ×1
gcc ×1
h.264 ×1
python ×1
rtmp ×1