2015-10-15 150 views
1

希望对ffmpeg专家来说一个简单的问题!ffmpeg将视频转换为图像,同时正在编写视频文件

我目前转换大(+ 6GB)MPEG视频到一个图像序列 - 这是工作良好使用下面的ffmpeg命令:

的ffmpeg -i “input.mpeg” -vf - FPS = FPS = 2 -f image2 -qscale 1 -s 1026x768“output%6d.jpg”

但是,我必须等待文件完成写入磁盘之前,我启动ffmpeg - 但这需要一个好时间左右,以便完成写作,但我注意到,ffmpeg可以在写入磁盘时开始读取文件 - 这里唯一的障碍是它到达文件的末尾并在文件写完之前停止...

问题是,有没有一种方法可以将ffmpeg以相同的速度转换为图像序列(而不是退出?)...或知道要等待下一帧从源写入。 (不幸的是输入不支持流媒体,我只得到一个网络驱动器和文件工作..)我以为我读的地方,ffmpeg可以处理视频帧率,但似乎无法找到这个命令的爱或金钱多克!

谢谢!

回答

1

您需要替换函数调用ffmpeg用于读取文件,使用那些将重试直到文件完成写入的文件。

首先,你可以编写你自己的处理器,并提供一个回调到ffio_init_context(),它会重试读取,直到文件被完全写入(你必须确定一个函数的方法能够告诉文件完成)。

其次,你可以决定哪些函数调用ffmpeg用来读取文件(可能read()fread()),并使用LD_PRELOAD夹着一个替代品,将重试,直到该文件已完成写入。这有点hackish,但它可以工作。像这样的东西(这仅仅是现成的,袖口的代码演示如何能做到这一点。如果你幸运的话,这可能连工作...。):

read.c:

// most libc implementations also provide another symbol 
// for library functions that starts with "_" 
extern ssize_t _read(int, void *, size-t); 

ssize_t read(int fd, void *buffer, size_t bytes) 
{ 
    ssize_t bytesRead; 
    for (;;) 
    { 
     bytesRead = _read(fd, buffer, bytes); 
     if (bytesRead != 0 || fileIsComplete(fd)) 
     { 
      break; 
     } 
    } 

    return (bytesRead); 
} 

您需要执行fileIsComplete()以检查文件是否已完全写入 - 如果文件尚未完成,请稍后将其编辑为sleep,否则您将会疯狂地旋转。如果ffmpeg未使用read(),则必须找出它正在使用的内容,例如fread()

如果libc中不具备的功能(S)ffmpeg备用下划线为前缀的符号用来读取这个文件,你必须做这样的事情(例如是fread()

FREAD。 C:

// function pointer to the real fread() function 
static size_t (*real_fread)(void *, size_t, size_t, FILE *) = NULL; 

size_t fread(void *buffer, size_t size, size_t n, FILE *stream) 
{ 
    // might need to mutex this for multithreaded apps 
    if (real_fread == NULL) 
    { 
     real_fread = dlsym(RTLD_NEXT, "fread"); 
    } 

    size_t result; 

    for (;;) 
    { 
     result = real_fread(buffer, size, n, stream); 
     if ((result != 0) || fileIsComplete(stream)) 
     { 
      break; 
     } 
    } 

    return(result); 
} 

只需编译插入C代码到一个共享对象和使用LD_PRELOAD有ffmpeg使用插入read()功能需要注意的是在这两种情况下,你必须添加适当的头文件(或可能跳过。他们因为你可能会得到重新宣布的错误 - 在哪些c因为您可能必须自己提供像RTLD_NEXT这样的值的正确定义)。

这样做可能会非常棘手获得工作的权利,如所有调用您的插入功能(S)将通过您的图书馆与你的LD_PRELOAD组运行的任何进程。您可能最好使用包装脚本来设置LD_PRELOAD,然后运行ffmpeg,因此只需要处理ffmpeg与插入库的配合。

ffmpeg可能无法很好地处理部分读取 - 您可能需要修改代码以保持读取,直到文件完成或读取了一定数量的字节,例如请求的字节数。