From dcfe9b4b83a7ca25c9d58108641fb1c5a2ab9e45 Mon Sep 17 00:00:00 2001 From: kira1928 Date: Tue, 9 Jul 2024 23:32:18 +0900 Subject: [PATCH] fix ffmpeg race panic --- README.md | 12 ----------- src/pkg/parser/ffmpeg/ffmpeg.go | 37 ++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index e2f64c8b..6bed8670 100644 --- a/README.md +++ b/README.md @@ -72,12 +72,6 @@ Bililive-go是一个支持多种直播平台的直播录制工具 滋瓷 - - twitch - www.twitch.tv - TODO - - OPENREC www.openrec.tv @@ -120,12 +114,6 @@ Bililive-go是一个支持多种直播平台的直播录制工具 滋瓷 - - 快手 - live.kuaishou.com - 滋瓷(不稳定) - 滋瓷 - YY直播 www.yy.com diff --git a/src/pkg/parser/ffmpeg/ffmpeg.go b/src/pkg/parser/ffmpeg/ffmpeg.go index 7147ba83..f7c23b33 100644 --- a/src/pkg/parser/ffmpeg/ffmpeg.go +++ b/src/pkg/parser/ffmpeg/ffmpeg.go @@ -55,6 +55,7 @@ type Parser struct { statusReq chan struct{} statusResp chan map[string]string + cmdLock sync.Mutex } func (p *Parser) scanFFmpegStatus() <-chan []byte { @@ -166,20 +167,30 @@ func (p *Parser) ParseLiveStream(ctx context.Context, url *url.URL, live live.Li } args = append(args, file) - p.cmd = exec.Command(ffmpegPath, args...) - if p.cmdStdIn, err = p.cmd.StdinPipe(); err != nil { - return err - } - if p.cmdStdout, err = p.cmd.StdoutPipe(); err != nil { - return err - } - if p.debug { - p.cmd.Stderr = os.Stderr - } - if err = p.cmd.Start(); err != nil { - p.cmd.Process.Kill() + + // p.cmd operations need p.cmdLock + func() { + p.cmdLock.Lock() + defer p.cmdLock.Unlock() + p.cmd = exec.Command(ffmpegPath, args...) + if p.cmdStdIn, err = p.cmd.StdinPipe(); err != nil { + return + } + if p.cmdStdout, err = p.cmd.StdoutPipe(); err != nil { + return + } + if p.debug { + p.cmd.Stderr = os.Stderr + } + if err = p.cmd.Start(); err != nil { + p.cmd.Process.Kill() + return + } + }() + if err != nil { return err } + go p.scheduler() err = p.cmd.Wait() if err != nil { @@ -190,6 +201,8 @@ func (p *Parser) ParseLiveStream(ctx context.Context, url *url.URL, live live.Li func (p *Parser) Stop() (err error) { p.closeOnce.Do(func() { + p.cmdLock.Lock() + defer p.cmdLock.Unlock() if p.cmd.ProcessState == nil { if p.cmdStdIn != nil && p.cmd.Process != nil { if _, err = p.cmdStdIn.Write([]byte("q")); err != nil {