为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Golang中的不同功能中杀死命令Exec

如何在Golang中的不同功能中杀死命令Exec

Go
繁星点点滴滴 2023-01-03 17:05:22
我正在使用命令 exec 运行 FFMPEG 来制作基于 Web 的屏幕录制。这里我创建了一个 startRecording 函数,但我仍然对在 stopRecording 函数中停止命令进程感到困惑,因为该命令是在 startRecording 函数中执行的。如何在stopRecording函数中停止srartRecording函数中已经运行的进程?这是我的代码//Handler to create room/start recordfunc 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 FFMPEGfunc 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: %v\n", strings.Join(ffmpeg.Args, " "))                if err := ffmpeg.Run(); err != nil {            return        }        //fmt.Printf("FFMPEG output:\n%v\n", 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 Recordingfunc stopRecording(ctx context.Context) error {//Code stop recording in here} 感谢您的提前
查看完整描述

1 回答

?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

根据评论的要求。


基本思想是使用全局存储来存储您的活动命令。它不一定是全局的,但您需要有更大的范围,以便您的函数可以访问它。


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()

}

您可能想使用 sync.Mutexsync.RWMutex来避免并发映射写入


所以你的commands云看起来像:


type Commands struct {

    sync.RWMutex

    items map[string]*exec.Cmd

}

// use Commands.Lock() for writing, Commands.RLock() for reading


查看完整回答
反对 回复 2023-01-03
  • 1 回答
  • 0 关注
  • 125 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号