Linux 如何远程停止ffmpeg?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9722624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to stop ffmpeg remotely?
提问by Adam
I'm running ffmpeg on another machine for screen capture. I'd like to be able to stop it recording remotely. FFMPEG requires that q is pressed to stop encoding as it has to do some finalization to finish the file cleanly. I know I could kill it with kill/killall however this can lead to corrupt videos.
我在另一台机器上运行 ffmpeg 进行屏幕截图。我希望能够远程停止录制。FFMPEG 要求按下 q 以停止编码,因为它必须进行一些最终确定才能干净利落地完成文件。我知道我可以用 kill/killall 杀死它,但这会导致视频损坏。
Press [q] to stop encoding
I can't find anything on google specifically for this, but some there is suggestion that echoing into /proc//fd/0 will work.
我在谷歌上找不到任何专门针对此的内容,但有人建议回显到 /proc//fd/0 会起作用。
I've tried this but it does not stop ffmpeg. The q is however shown in the terminal in which ffmpeg is running.
我试过这个,但它不会停止 ffmpeg。然而, q 显示在运行 ffmpeg 的终端中。
echo -n q > /proc/16837/fd/0
So how can I send a character to another existing process in such a way it is as if it were typed locally? Or is there another way of remotely stopping ffmpeg cleanly.
那么如何将字符发送到另一个现有进程,就像在本地键入一样?或者是否有另一种方法可以远程干净地停止 ffmpeg。
采纳答案by sashoalm
Newer versions of ffmpeg don't use 'q' anymore, at least on Ubuntu Oneiric, instead they say to press Ctrl+C to stop them. So with a newer version you can simply use 'killall -INT' to send them SIGINT instead of SIGTERM, and they should exit cleanly.
较新版本的 ffmpeg 不再使用“q”,至少在 Ubuntu Oneiric 上,他们说要按 Ctrl+C 来停止它们。因此,对于较新的版本,您可以简单地使用 'killall -INT' 向它们发送 SIGINT 而不是 SIGTERM,并且它们应该干净地退出。
回答by TheHelper
Here's a neat trick I discovered when I was faced with this problem: Make an empty file (it doesn't have to be a named pipe or anything), then write 'q' to it when it's time to stop recording.
当我遇到这个问题时,我发现了一个巧妙的技巧:创建一个空文件(它不必是命名管道或任何东西),然后在停止录制时向其中写入“q”。
- $ touch stop
- $ <./stop ffmpeg -i ... output.ext >/dev/null 2>>Capture.log &
- $ wait for stopping time
- $ echo 'q' > stop
- $ 触摸停止
- $ <./stop ffmpeg -i ... output.ext >/dev/null 2>>Capture.log &
- $ 等待停止时间
- $ echo 'q' > 停止
FFmpeg stops as though it got 'q' from the terminal STDIN.
FFmpeg 停止,就好像它从终端 STDIN 得到“q”一样。
回答by cartola
You can also try to use "expect" to automate the execution and stop of the program. You would have to start it using some virtual shell like screen
, tmux
or byobu
and then start the ffmpeg
inside of it. This way you would be able to get again the virtual shell screen and give the "q" option.
您也可以尝试使用“expect”来自动执行和停止程序。您必须使用一些虚拟外壳启动它,例如screen
,tmux
或者byobu
然后启动ffmpeg
它的内部。这样您就可以再次获得虚拟外壳屏幕并提供“q”选项。
Locally or remotely start a virtual shell session, lets say with "screen". Name the session with
-S
option, likescreen -S recvideo
Then you can start the ffmpeg as you like. You can, optionally, detach from this session with a Ctrl+a + d.Connect to the machine where the ffmpeg is running inside the screen (or tmux or whatever) and reconnect to it:
screen -d -RR recvideo
and then send the "q"
本地或远程启动虚拟 shell 会话,让我们说“屏幕”。使用
-S
选项命名会话,例如screen -S recvideo
然后您可以根据需要启动 ffmpeg。您可以选择使用 Ctrl+a + d 与此会话分离。连接到 ffmpeg 在屏幕内运行的机器(或 tmux 或其他)并重新连接到它:
screen -d -RR recvideo
然后发送“q”
To do that from inside a script you can then use expect, like:
要从脚本内部执行此操作,您可以使用 expect,例如:
prompt="> "
expect << EOF
set timeout 20
spawn screen -S recvideo
expect "$prompt"
send -- "ffmpeg xxxxx\r"
set timeout 1
expect eof
EOF
Then, in another moment or script point or in another script you recover it:
然后,在另一个时刻或脚本点或另一个脚本中恢复它:
expect << EOF
set timeout 30
spawn screen -d -RR recvideo
expect "$prompt"
send -- "q"
expect "$prompt"
send -- "exit\r"
expect eof
EOF
You can also automate the whole ssh
session with expect, passing a sequence of commands and "expects" to do what you want.
您还可以ssh
使用 expect自动执行整个会话,传递一系列命令和“期望”以执行您想要的操作。
回答by Rub
Elaborating on the answer from sashoalm, i have tested both scenarios, and here are the results:
详细说明 sashoalm 的答案,我测试了这两种情况,结果如下:
My experiments shows that doing
我的实验表明,做
killall --user $USER --ignore-case --signal INT ffmpeg
Produces the following on the console where ffmpeg was running
在运行 ffmpeg 的控制台上生成以下内容
Exiting normally, received signal 2.
While doing
在做的时候
killall --user $USER --ignore-case --signal SIGTERM ffmpeg
Produces
生产
Exiting normally, received signal 15.
So it looks that ffmpeg is fine with both signals.
所以看起来 ffmpeg 对这两个信号都很好。
System: Debian GNU/Linux 9 (stretch), 2020-02-28
系统:Debian GNU/Linux 9 (stretch), 2020-02-28