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 {