Saya mempunyai program yang menggunakan ffmpeg untuk menstrim kamera rtsp ke format hls. Apabila ffmpeg berjalan di latar belakang, buat goroutine untuk setiap pautan rtsp
Strim ditambah dengan kod berikut.
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 } }() }
}
Jalankan fungsi penstriman arahan ffmpeg.
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 } }}
Matlamat saya adalah untuk menghentikan setiap proses os.exec (arahan ffmpeg) atau sekurang-kurangnya menutup semua goroutine di bawah arahan ffmpeg tanpa menutup pelayan gentian.
** Golang newbie perlukan bantuan **
Ini kod berfungsi:
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() } }
Dan mulakan penstriman:
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 } }
.
Ini berkesan untuk saya, sekarang saya tidak menemui jalan yang lebih baik. Jika sesiapa mempunyai cara yang lebih baik sila komen.
Atas ialah kandungan terperinci Tutup goroutine yang dijana oleh titik akhir Fiber. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!