我的编辑需求相当简单 - 我需要剪切一些视频,可能在它们之间插入一些 PNG,然后合并这些视频(不需要过渡、效果等)。基本上,pitivi
可以做我想做的事 - 只是,我使用相机拍摄的 640x480 30 fps AVI,只要我放入这种素材几分钟,pitivi
预览就会开始冻结,因此无法使用。
因此,我开始寻找 Linux 的命令行工具;我猜只有ffmpeg
(命令行 - 使用 ffmpeg 剪切视频 - 智库101 - 一个优秀的智库) 和mplayer
(Sam - 在 Linux 下使用 mencoder 编辑视频文件) 是迄今为止的候选者,但我找不到我想到的用法的例子。
基本上,我想象有一个编码器和播放器工具(如ffmpeg
vs ffplay
;或mencoder
vs mplayer
) - 这样,首先,可以在命令行上直接指定编辑序列,最好使用帧分辨率 - 伪代码看起来像:
videnctool -compose --file=vid1.avi --start=00:00:30:12 --end=00:01:45:00 --file=vid2.avi --start=00:05:00:00 --end=00:07:12:25 --file=mypicture.png --duration=00:00:02:00 --file=vid3.avi --start=00:02:00:00 --end=00:02:45:10 --output=editedvid.avi
...或者,它可以有一个“播放列表”文本文件,例如:
vid1.avi 00:00:30:12 00:01:45:00
vid2.avi 00:05:00:00 00:07:12:25
mypicture.png - 00:00:02:00
vid3.avi 00:02:00:00 00:02:45:10
...因此可以这样调用
videnctool -compose --playlist=playlist.txt --output=editedvid.avi
这里的想法是,所有视频都采用相同的格式 - 允许该工具避免转码,而只执行“原始复制”(mencoder
如复制codec: " -oac copy -ovc copy
") - 或者如果没有,未压缩的音频/视频也可以(尽管会占用一些空间)。对于静态图像,该工具将使用视频文件设置的编码。
问题是,到目前为止我可以看到mencoder
并且ffmpeg
可以对单个文件进行操作;例如从单个文件中剪切单个部分,或合并文件(mencoder
也有编辑决策列表 (EDL),可以用来做框架精确切割- 因此您可以定义多个剪切区域,但它又归属于单个文件)。这意味着我必须首先从各个文件(每个文件都需要磁盘上的临时文件)中剪切片段,然后将它们合并到最终的视频文件中。
然后我会想象,有一个相应的播放器工具,它可以读取与编码工具相同的命令行选项格式/播放列表文件 - 除了它不会生成输出文件,而是播放视频;例如用伪代码:
vidplaytool --playlist=playlist.txt --start=00:01:14 --end=00:03:13
...并且,如果有足够的内存,它会在 RAM 中生成低分辨率视频预览,并在窗口中播放,同时提供一些有限的交互(mplayer
如键盘快捷键用于播放、暂停、倒带、步进帧)。当然,我认为开始和结束时间指的是整个播放列表,并且包括播放列表中可能出现在该区域的任何文件。
因此,所有这一切的最终结果是:命令行操作;编辑时没有临时文件 - 并且在呈现最终输出时也没有临时文件(也没有转码)......我自己认为这会很好。
因此,虽然我认为以上所有内容可能有点牵强 - 是否存在任何可以近似于上述工作流程的东西?
答案1
答案2
好的,因为我找不到太多关于melt
命令行用法的信息,这里有一些注释......(之后,请参阅这个答案)使用进程替换来欺骗需要文件的程序,并使用特定扩展名作为参数? - Unix&Linux Stack Exchange脚本示例bash
通过
首先 - 有一个 Ubuntu/Debian 软件包melt
(我有 Ubuntu 11.04 和 MLT melt 0.6.2);链接由@Ielton适用于“Media Lovin' Toolkit”(MLT)Wiki,它melt
是 的一部分(但也是openshot
的一部分kdenlive
)。以下是来自其 git 的文档文本文件的链接:mltframework.org/mlt.git/tree - 文档/;请注意,维基百科上有一个关于构建脚本。
目前,我遇到的最大(唯一)问题是,我找不到导出未压缩视频合成的方法(无论是作为png
帧,还是某种未压缩的视频格式)。
首先,在命令行中,melt
您可以通过帧控制播放;例如,要“创建” 15 帧长的白色空白,并使用内置播放器查看它melt
,请使用
melt -blank 15
当您使用 查看时melt
,您还将获得stderr
内置播放器的命令行信息:
$ melt -blank 15
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|1=-10| |2= -5| |3= -2| |4= -1| |5= 0| |6= 1| |7= 2| |8= 5| |9= 10|
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
+---------------------------------------------------------------------+
| H = back 1 minute, L = forward 1 minute |
| h = previous frame, l = next frame |
| g = start of clip, j = next clip, k = previous clip |
| 0 = restart, q = quit, space = play |
+---------------------------------------------------------------------+
Current Position: 15
播放完成后melt
,它不会退出 - 因此您应该键入q
以退出它。
需要注意的是,在 中有所谓的“生产者”和“消费者” melt
。如果没有指定,则默认的“消费者”是SDL(简单直接媒体层)窗口播放视频;因此上述命令与以下命令相同:
melt -blank 15 -consumer sdl
因此,如果我们想保存melt
显示的内容,我们应该将消费者更改为支持文件格式的消费者。要获取消费者列表:
$ melt -query "consumers"
---
consumers:
- sdl
- sdl_audio
- sdl_preview
- sdl_still
- gtk2_preview
- avformat
- libdv
- xml
- decklink
- null
...
消费者libdv
将直接输出 DV 格式的数据stdout
,因此要将视频保存到.dv
文件,您需要执行以下操作:
melt -blank 15 -consumer libdv > test.dv
请注意,从列出的消费者来看,我尝试过的唯一可以在另一个应用程序中打开的格式是libdv
(我用作vlc
另一个应用程序);但是,对于不同类型的转码,这可能会失败(例如,如果我尝试转换文件中的片段而不是空白,则.flv
生成的 .dv 文件可以打开并播放vlc
,但已损坏)。
现在編輯部分;本质上,你可以指定一系列文件名/in/out 节直接在命令行上;假设你有一个文件,video.avi
--那么你可以这样做:
melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79
或者格式稍微好一点的:
melt \
video.avi in=30 out=79 \
-blank 15 \
video.avi in=30 out=79
这意味着video.avi
将播放从第 30 帧到第 79 帧的视频;然后是 15 帧的空白;然后video.avi
再次播放从第 30 帧到第 79 帧的序列。
.png
要在视频编辑合成中使用图像(例如),请执行以下操作:
melt \
video.avi in=30 out=79 \
test.png in=0 out=15 \
video.avi in=30 out=79 \
-blank 15
请注意,对于test.png
,in=
参数不需要为 0 - 但是,图像将显示out
-in
时间;在这种情况下,最简单的方法是in=0
完全省略该参数。
好消息是,这个编辑序列可以保存 - 或者称之为melt
,序列化- 到一个文件;注意二序列化方式有:“简单”或 XML。例如,要将上述命令保存为“简单”序列化文件,我们只需-serialise [filename]
在命令中添加开关:
$ melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -serialise file.melt
Project saved as file.melt.
现在file.melt
包含:
video.avi
in=30
out=79
-blank
15
video.avi
in=30
out=79
看起来,这种“简单”的序列化文件格式不包含“注释”字符 - 如果我尝试添加“ # comment
”行,melt
则会抱怨:“无法加载“# 条评论”'(但除此之外,似乎这一行被忽略了,并且播放仍然继续)。“ .melt
”似乎是一个melt
识别为简单序列化文件的扩展。
现在,为了重新播放这个序列化文件,我们原则上只需调用melt file.melt
- 但是,更完整的命令行应该是:
melt melt_file:file.melt -consumer sdl
...这意味着:使用melt_file
“生产者”打开file.melt
,并在“消费者” sdl
(窗口)上呈现其框架。
请注意,我的经验是,(比如说).flv
视频在命令行上播放没有问题 - 但是,当它们在file.melt
序列化文件中指定时会导致分段错误!.dv
由其自己制作的视频melt
似乎在file.melt
...中运行良好。
XML 类型的序列化可以通过使用-consumer xml:
开关 (代替-serialise
)——因此上面的例子现在是:
melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -consumer xml:file.mlt
要“播放”新生成的file.mlt
XML 文件,现在可以直接执行melt file.mlt
- 或者,更完整的命令行是:
melt xml:file.mlt -consumer sdl
...这意味着:使用xml
“生产者”(请注意,以前它是消费者) 打开file.mlt
,并在“消费者” sdl
(窗口) 上呈现其框架。
请注意,在这种情况下,我遇到的问题是,.flv
使用简单序列化文件会导致段错误的相同视频,使用 XML 序列化文件却可以正常运行!
在这种情况下,生成的file.mlt
XML 文件具有更多设置,例如分辨率、帧速率、编解码器信息等 - 但直接在文本编辑器中使用也更加困难:
<?xml version="1.0" encoding="utf-8"?>
<mlt root="/path/to" title="video.avi">
<profile description="automatic" width="320" height="240" progressive="1" sample_aspect_num="1" sample_aspect_den="1" display_aspect_num="320" display_aspect_den="240" frame_rate_num="25" frame_rate_den="1" colorspace="601"/>
<producer id="producer0" in="30" out="79">
<property name="mlt_type">producer</property>
<property name="aspect_ratio">1.000000</property>
<property name="length">125</property>
<property name="eof">pause</property>
<property name="resource">video.avi</property>
<property name="meta.media.nb_streams">2</property>
<property name="meta.media.0.stream.type">video</property>
<property name="meta.media.0.stream.frame_rate">25.000000</property>
<property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
<property name="meta.media.0.codec.frame_rate">25.000000</property>
<property name="meta.media.0.codec.pix_fmt">yuv420p</property>
<property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
<property name="meta.media.0.codec.colorspace">601</property>
<property name="meta.media.0.codec.name">mpeg4</property>
<property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
<property name="meta.media.0.codec.bit_rate">0</property>
<property name="meta.media.1.stream.type">audio</property>
<property name="meta.media.1.codec.sample_fmt">s16</property>
<property name="meta.media.1.codec.sample_rate">22050</property>
<property name="meta.media.1.codec.channels">1</property>
<property name="meta.media.1.codec.name">mp2</property>
<property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
<property name="meta.media.1.codec.bit_rate">64000</property>
<property name="seekable">1</property>
<property name="meta.media.sample_aspect_num">1</property>
<property name="meta.media.sample_aspect_den">1</property>
<property name="meta.attr.title.markup"></property>
<property name="meta.attr.author.markup"></property>
<property name="meta.attr.copyright.markup"></property>
<property name="meta.attr.comment.markup"></property>
<property name="meta.attr.album.markup"></property>
<property name="audio_index">1</property>
<property name="video_index">0</property>
<property name="mlt_service">avformat</property>
</producer>
<producer id="producer1" in="30" out="79">
<property name="mlt_type">producer</property>
<property name="aspect_ratio">1.000000</property>
<property name="length">125</property>
<property name="eof">pause</property>
<property name="resource">video.avi</property>
<property name="meta.media.nb_streams">2</property>
<property name="meta.media.0.stream.type">video</property>
<property name="meta.media.0.stream.frame_rate">25.000000</property>
<property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
<property name="meta.media.0.codec.frame_rate">25.000000</property>
<property name="meta.media.0.codec.pix_fmt">yuv420p</property>
<property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
<property name="meta.media.0.codec.colorspace">601</property>
<property name="meta.media.0.codec.name">mpeg4</property>
<property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
<property name="meta.media.0.codec.bit_rate">0</property>
<property name="meta.media.1.stream.type">audio</property>
<property name="meta.media.1.codec.sample_fmt">s16</property>
<property name="meta.media.1.codec.sample_rate">22050</property>
<property name="meta.media.1.codec.channels">1</property>
<property name="meta.media.1.codec.name">mp2</property>
<property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
<property name="meta.media.1.codec.bit_rate">64000</property>
<property name="seekable">1</property>
<property name="meta.media.sample_aspect_num">1</property>
<property name="meta.media.sample_aspect_den">1</property>
<property name="meta.attr.title.markup"></property>
<property name="meta.attr.author.markup"></property>
<property name="meta.attr.copyright.markup"></property>
<property name="meta.attr.comment.markup"></property>
<property name="meta.attr.album.markup"></property>
<property name="audio_index">1</property>
<property name="video_index">0</property>
<property name="mlt_service">avformat</property>
</producer>
<playlist id="playlist0">
<entry producer="producer0" in="0" out="49"/>
<blank length="16"/>
<entry producer="producer1" in="0" out="49"/>
</playlist>
<tractor id="tractor0" title="video.avi" global_feed="1" in="0" out="115">
<track producer="playlist0"/>
</tractor>
</mlt>
答案3
ffmpeg 针对此问题的解决方案如下所示:
mkfifo temp1 temp2 temp3
ffmpeg -i input.wmv -ss 30 -to 60 -c copy output.wmv temp1 2> /dev/null & \
ffmpeg -i input2.wmv -t 60 -c copy temp2 2> /dev/null & \
ffmpeg -i input3.wmv -i image.png -filter_complex "[0:v][1:v] \
overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy temp3 2> /dev/null & \
ffmpeg -f mpegts -i "concat:temp1|temp2|temp3" -c copy output.mp4
它使用命名管道,因此无需在磁盘上创建临时文件,并允许您剪切视频片段并添加图像。
此示例使用第一个输入的时间 30-60,然后添加第二个输入的第一分钟,然后插入图像文件,然后插入整个第三个视频。
代码摘自:
ffmpeg 连接页面: https://trac.ffmpeg.org/wiki/Concatenate
超级用户页面使用 ffmpeg 剪切视频
超级用户页面https://video.stackexchange.com/questions/12105/add-an-image-in-front-of-video-using-ffmpeg
答案4
如果您需要一些非常简单的东西,那么也许您可以使用我创建的这个名为 EDITLY 的工具(使用 ffmpeg)。
以下是您使用的方法:
npm install -g editly
创建一个文件edit.json5
,内容如下:
{
defaults: {
// editly defaults to randomizing transitions, but since you wanted no transitions, set it to null
transition: null,
},
clips: [
// cutFrom/cutTo values are in seconds
{ layers: [{ type: 'video', path: 'vid1.avi', cutFrom: 30.12, cutTo: 105 },
{ layers: [{ type: 'video', path: 'vid2.avi', cutFrom: 300, cutTo: 432.25 },
{ duration: 2, layers: [{ type: 'image', path: 'mypicture.png' },
{ layers: [{ type: 'video', path: 'vid3.avi', cutFrom: 120, cutTo: 165.1 },
],
}
现在运行:
editly edit.json5 --out editedvid.mp4
您可能还需要一些其他功能,如标题屏幕、文本或字幕覆盖和生成的背景。
请参阅项目页面了解更多信息:https://github.com/mifi/editly