- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有 100 张图片 (PNG),我想使用这些图片制作视频。为此,我正在使用 ffmpeg 库。使用命令行我可以轻松创建视频。但是我如何通过编码来做到这一点?
我们将不胜感激。
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif
extern "C"
{
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
}
#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
static void video_encode_example(const char *filename, int codec_id)
{
AVCodec *codec;
AVCodecContext *c= NULL;
int i, out_size, size, x, y, outbuf_size;
FILE *f;
AVFrame *picture;
uint8_t *outbuf;
int nrOfFramesPerSecond =25;
int nrOfSeconds =1;
printf("Video encoding\n");
// find the mpeg1 video encoder
codec = avcodec_find_encoder((CodecID) codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
c = avcodec_alloc_context3(codec);
picture= avcodec_alloc_frame();
// put sample parameters
c->bit_rate = 400000;
// resolution must be a multiple of two
c->width = 352;
c->height = 288;
// frames per second
c->time_base= (AVRational){1,25};
c->gop_size = 10; //emit one intra frame every ten frames
c->max_b_frames=1;
c->pix_fmt = PIX_FMT_YUV420P;
if(codec_id == CODEC_ID_H264)
av_opt_set(c->priv_data, "preset", "slow", 0);
// open it
if (avcodec_open2(c, codec, NULL) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
f = fopen(filename, "wb");
if (!f) {
fprintf(stderr, "could not open %s\n", filename);
exit(1);
}
// alloc image and output buffer
outbuf_size = 100000;
outbuf = (uint8_t*) malloc(outbuf_size);
// the image can be allocated by any means and av_image_alloc() is
// * just the most convenient way if av_malloc() is to be used
av_image_alloc(picture->data, picture->linesize,
c->width, c->height, c->pix_fmt, 1);
// encode 1 second of video
int nrOfFramesTotal = nrOfFramesPerSecond * nrOfSeconds;
// encode 1 second of video
for(i=0;i < nrOfFramesTotal; i++) {
fflush(stdout);
// prepare a dummy image
for(y=0;y<c->height;y++) {
for(x=0;x<c->width;x++) {
picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
}
}
// Cb and Cr
for(y=0;y<c->height/2;y++) {
for(x=0;x<c->width/2;x++) {
picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
}
}
// encode the image
out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
printf("encoding frame %3d (size=%5d)\n", i, out_size);
fwrite(outbuf, 1, out_size, f);
}
// get the delayed frames
for(; out_size; i++) {
fflush(stdout);
out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL);
printf("write frame %3d (size=%5d)\n", i, out_size);
fwrite(outbuf, 1, out_size, f);
}
// add sequence end code to have a real mpeg file
outbuf[0] = 0x00;
outbuf[1] = 0x00;
outbuf[2] = 0x01;
outbuf[3] = 0xb7;
fwrite(outbuf, 1, 4, f);
fclose(f);
free(outbuf);
avcodec_close(c);
// av_free(c);
// av_free(picture->data[0]);
// av_free(picture);
printf("\n");
}
int main(int argc, char **argv)
{
const char *filename;
avcodec_register_all();
if (argc <= 1) {
video_encode_example("/home/radix/Desktop/OpenCV/FFMPEG_Output/op89.png", AV_CODEC_ID_H264);
} else {
filename = argv[1];
}
return 0;
}
最佳答案
这个问题一次又一次出现的原因是因为您正在使用 encoding_example.c作为您的引用。请不要那样做。这个例子中最根本的错误是它没有告诉你编解码器和容器之间的区别。事实上,它完全忽略了容器。
什么是编解码器?编解码器是一种压缩媒体类型的方法。例如,H264 将压缩原始视频。想象一个 1080p 视频帧,它通常采用 YUV 格式,具有 4:2:0 色度子采样。原始数据,这是每帧 1080*1920*3/2 字节,即 ~3MB/f。对于 60fps,这是 180MB/秒,或 1.44 吉比特/秒 (gbps)。这是很多数据,所以我们压缩它。在该分辨率下,对于 H264、HEVC 或 VP9 等现代编解码器,您可以获得几兆比特/秒 (mbps) 的质量。对于音频,AAC 或 Opus 等编解码器很受欢迎。
什么是容器?容器接收视频或音频(或字幕)数据包(压缩或未压缩)并将它们交织在一起,以便组合存储在单个输出文件中。因此,您得到的不是一个视频文件和一个音频文件,而是一个将两者的数据包交织在一起的文件。这允许有效的查找和索引,它通常还允许添加元数据存储(“作者”、“标题”)等。流行容器的示例有 MOV、MP4(实际上只是 mov)、AVI、Ogg、Matroska 或 WebM(实际上只是 matroska)。
(如果需要,您可以将纯视频数据存储在文件中。对于 H264,这称为“annexb”原始 H264。这实际上是您在上面所做的。那么为什么它不起作用?好吧,您正在忽略 SPS 和 PPS 之类的“ header ”数据包。这些位于 avctx->extradata 中,需要在第一个视频数据包之前写入。使用容器会为您解决这个问题,但您没有,所以它没用。)
如何在 FFmpeg 中使用容器?参见例如this发布,特别是调用函数的部分,如 avformat_write_*()
(基本上任何听起来像输出的东西)。我很乐意回答更具体的问题,但我认为上面的帖子应该能为您消除大部分困惑。
关于c++ - 使用 ffmpeg 创建视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36687188/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!