如何在Golang中杀死差异函数中的Exec命令



我正在使用命令exec运行FFMPEG进行基于web的屏幕录制。在这里,我创建了一个startRecording函数,但我仍然对停止stopRecording函数中的命令进程感到困惑,因为该命令是在startRecording功能中执行的。如何在stopRecording函数中停止srartRecording函数已在运行的进程?

这是我的代码

//Handler to create room/start record
func RoomCreate(c *fiber.Ctx) error {
fileName := "out.mp4"
fmt.Println(fileName)
if len(os.Args) > 1 {
fileName = os.Args[1]
}

errCh := make(chan error, 2)
ctx, cancelFn := context.WithCancel(context.Background())
// Call to function startRecording
go func() { errCh <- startRecording(ctx, fileName) }()
go func() {
errCh <- nil
}()
err := <-errCh
cancelFn()
if err != nil && err != context.Canceled {
log.Fatalf("Execution failed: %v", err)
}

return c.Redirect(fmt.Sprintf("/room/%s", guuid.New().String()))
}

//Function to run command FFMPEG
func startRecording(ctx context.Context, fileName string) error {
ctx, cancelFn := context.WithCancel(ctx)
defer cancelFn()
// Build ffmpeg
ffmpeg := exec.Command("ffmpeg",
"-f", "gdigrab",
"-framerate", "30",
"-i", "desktop",
"-f", "mp4",
fileName,
)
// Stdin for sending data
stdin, err := ffmpeg.StdinPipe()
if err != nil {
return err
}
//var buf bytes.Buffer
defer stdin.Close()
// Run it in the background
errCh := make(chan error, 1)
go func() {
fmt.Printf("Executing: %vn", strings.Join(ffmpeg.Args, " "))

if err := ffmpeg.Run(); err != nil {
return
}
//fmt.Printf("FFMPEG output:n%vn", string(out))
errCh <- err
}()
// Just start sending a bunch of frames
for {

// Check if we're done, otherwise go again
select {
case <-ctx.Done():
return ctx.Err()
case err := <-errCh:
return err
default:
}
}
}
//Here function to stop Recording
func stopRecording(ctx context.Context) error {
//Code stop recording in here
} 

感谢提前

根据评论要求。

基本思想是使用全局存储来存储活动命令。它不一定是全局的,但你需要有更大的范围,这样你的功能才能访问它

var commands = map[string]*exec.Cmd{}
func startRecording(fileName string) error {
ffmpeg := exec.Command("ffmpeg",
"-f", "gdigrab",
"-framerate", "30",
"-i", "desktop",
"-f", "mp4",
fileName,
)
commands[fileName] = ffmpeg
...
}
func stopRecording(fileName string) error {
cmd, ok := commands[fileName]
if !ok {
return errors.New("command not found")
}
defer func() {
delete(commands, fileName)
}()
return cmd.Process.Kill()
}

您可能想要使用同步。Mutex或sync。RWMutex以避免并发映射写入。

所以你的commands云看起来像:

type Commands struct {
sync.RWMutex
items map[string]*exec.Cmd
}
// use Commands.Lock() for writing, Commands.RLock() for reading

最新更新