猿问

如何在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: %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 Recording

func stopRecording(ctx context.Context) error {

//Code stop recording in here

感谢您的提前


繁星点点滴滴
浏览 171回答 1
1回答

汪汪一只猫

根据评论的要求。基本思想是使用全局存储来存储您的活动命令。它不一定是全局的,但您需要有更大的范围,以便您的函数可以访问它。var commands = map[string]*exec.Cmd{}func startRecording(fileName string) error {&nbsp; &nbsp; ffmpeg := exec.Command("ffmpeg",&nbsp; &nbsp; &nbsp; &nbsp; "-f", "gdigrab",&nbsp; &nbsp; &nbsp; &nbsp; "-framerate", "30",&nbsp; &nbsp; &nbsp; &nbsp; "-i", "desktop",&nbsp; &nbsp; &nbsp; &nbsp; "-f", "mp4",&nbsp; &nbsp; &nbsp; &nbsp; fileName,&nbsp; &nbsp; )&nbsp; &nbsp; commands[fileName] = ffmpeg&nbsp; &nbsp; ...}func stopRecording(fileName string) error {&nbsp; &nbsp; cmd, ok := commands[fileName]&nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; return errors.New("command not found")&nbsp; &nbsp; }&nbsp; &nbsp; defer func() {&nbsp; &nbsp; &nbsp; &nbsp; delete(commands, fileName)&nbsp; &nbsp; }()&nbsp; &nbsp; return cmd.Process.Kill()}您可能想使用&nbsp;sync.Mutex或sync.RWMutex来避免并发映射写入。所以你的commands云看起来像:type Commands struct {&nbsp; &nbsp; sync.RWMutex&nbsp; &nbsp; items map[string]*exec.Cmd}// use Commands.Lock() for writing, Commands.RLock() for reading
随时随地看视频慕课网APP

相关分类

Go
我要回答