2 回答
TA贡献1830条经验 获得超9个赞
我有时会遇到问题,您的代码不会终止youtube-dl进程。视频被转换,但过程被保留。作为第一个指标,观察进程计数,如下所示:
ps | grep youtube-dl | wc -l
可以让子进程超时,对于一个子进程,这看起来像这样:
package main
import (
"bytes"
"fmt"
"os/exec"
"time"
)
func main() {
// Sleep is used, so we can control how long it runs.
cmd := exec.Command("sleep", "2")
// Use a bytes.Buffer to get the output
var buf bytes.Buffer
cmd.Stdout = &buf
cmd.Start()
// Use a channel to signal completion so we can use a select statement
done := make(chan error)
go func() { done <- cmd.Wait() }()
// Start a timer, should be higher for your video conversion,
// I suggest you use a value that fits both your videos and server capabilities
timeout := time.After(2 * time.Second)
// The select statement allows us to execute based on which channel
// we get a message from first.
select {
case <-timeout:
// Timeout happened first, kill the process and print a message.
cmd.Process.Kill()
fmt.Println("Command timed out")
case err := <-done:
// Command completed before timeout. Print output and error if it exists.
fmt.Println("Output:", buf.String())
if err != nil {
fmt.Println("Non-zero exit code:", err)
}
}
}
在你的情况下,你可以更换
ffmpeg.Start()
youtubevideo.Start()
youtube.Start()
ffmpeg.Wait()
youtubevideo.Wait()
youtube.Wait()
和
ffmpeg.Start()
youtubevideo.Start()
youtube.Start()
commands := 3
done := make(chan error)
go func() { done <- ffmpeg.Wait() }()
go func() { done <- youtubevideo.Wait() }()
go func() { done <- youtube.Wait() }()
timeout := time.After(1 * time.Hour)
Loop:
for {
select {
case <-timeout:
ffmpeg.Process.Kill()
youtubevideo.Process.Kill()
youtube.Process.Kill()
log.Println("Conversion timed out")
break Loop
case err := <-done:
if err != nil {
log.Println("Non-zero exit code:", err)
}
commands = commands - 1
if commands == 0 {
break Loop
}
}
}
TA贡献1790条经验 获得超9个赞
因此,经过一些调试并在凯文的回答的帮助下。成功后好像youtube-dl没有关闭。
鉴于如果ffmpeg完成,那么让youtube-dl实例运行没有任何意义,并且由于Wait()函数正在等待youtube-dl完成,但它似乎从未发送完成信号,所以我继续并不得不添加一个 kill 来杀死子子进程。
所以我不得不添加改变这个
ffmpeg.Start()
youtubevideo.Start()
youtube.Start()
ffmpeg.Wait()
youtubevideo.Wait()
youtube.Wait()
对此
youtube.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
youtubevideo.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
ffmpeg.Start()
youtubevideo.Start()
youtube.Start()
ffmpeg.Wait()
syscall.Kill(-youtube.Process.Pid, syscall.SIGKILL)
syscall.Kill(-youtubevideo.Process.Pid, syscall.SIGKILL)
youtubevideo.Wait()
youtube.Wait()
请注意,因为它似乎产生了某种子子youtube.Process.Kill()进程,实际上并没有杀死该进程,这就是我必须使用的原因syscall,而且Setpgid: true
- 2 回答
- 0 关注
- 1217 浏览
添加回答
举报
