Close the goroutine generated by the Fiber endpoint

王林
Release: 2024-02-05 23:03:04
forward
1124 people have browsed it

关闭由 Fiber 端点生成的 goroutine

Question content

I have a program that uses ffmpeg to stream an rtsp camera to hls format. When ffmpeg runs in the background, create goroutine

for each rtsp link

The stream is added with the following code.

func streamprocess(data <-chan streamdata, ctx context.context) {
for v := range data {
    ctx, _ := context.withcancel(ctx)
    go func() {
        if !getstreams(v.camera_id) {
            var stream streamstate
            stream.camera_id = v.camera_id
            stream.state = true
            go stream(v, ctx)
            wg.wait()
        } else {
            return
        }
    }()
}
Copy after login

}

Run the streaming function of the ffmpeg command.

func Stream(meta StreamData, ctx context.Context) error {
    log.Println("Started Streaming")
    ffmpegCmd := exec.Command("ffmpeg", "-i", meta.rtsp, "-pix_fmt", "yuv420p", "-c:v", "libx264", "-preset", "ultrafast", "-b:v", "600k", "-c:a", "aac", "-b:a", "160k", "-f", "rtsp", fmt.Sprintf("rtsp://localhost:8554/%s", meta.camera_id))
    output, _ := ffmpegCmd.CombinedOutput()

    log.Println(string(output))

    for {
        select {
        case <-ctx.Done():
           log.Println("killing process")
           ffmpegCmd.Process.Kill()
           return nil
        }
    }}
Copy after login

My goal is to stop every os.exec process (ffmpeg command) or at least close all goroutines under the ffmpeg command without shutting down the fiber server.

** Golang newbie needs help **


Correct answer


This is the working code:

func streamprocess(data <-chan streamdata, ctx context.context) {
ctx, cancel := context.withcancel(ctx)
defer cancel()
for {
    select {
    case v, ok := <-data:
        if ok {
            go func() {
                if !getstreams(v.camera_id) {
                    var stream streamstate
                    stream.camera_id = v.camera_id
                    stream.state = true
                    go stream(v, ctx)
                }
            }()
        } else if !ok {
            cancel()
            return
        }
    case <-ctx.done():
        log.println("closed ctx")
        cancel()
    }

}
Copy after login

and start streaming:

func Stream(meta StreamData, ctx context.Context) error {
log.Println("Started Streaming")
err := exec.CommandContext(ctx, "ffmpeg", "-i", meta.rtsp, "-pix_fmt", "yuv420p", "-c:v", "libx264", "-preset", "ultrafast", "-b:v", "600k", "-c:a", "aac", "-b:a", "160k", "-f", "rtsp", fmt.Sprintf("rtsp://localhost:8554/%s", meta.camera_id)).Run()

if err != nil {
    log.Println("error in streaming", err)
    return err
}

log.Println(string("waiting for closure"))
for {
    select {
    case <-ctx.Done():
        log.Println("killing process")          
        return nil
    case <-time.After(2* time.second):
        log.Println("started default context")
        return nil
    }

}
Copy after login

.

This worked for me, now I don't find a better way. If anyone has a better way please comment.

The above is the detailed content of Close the goroutine generated by the Fiber endpoint. For more information, please follow other related articles on the PHP Chinese website!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!