J'ai un programme qui utilise ffmpeg pour diffuser une caméra rtsp au format hls. Lorsque ffmpeg s'exécute en arrière-plan, créez une goroutine pour chaque lien rtsp
Le flux est ajouté avec le code suivant.
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 } }() }
}
Exécutez la fonction de streaming de la commande 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 } }}
Mon objectif est d'arrêter chaque processus os.exec (commande ffmpeg) ou au moins de fermer toutes les goroutines sous la commande ffmpeg sans arrêter le serveur fibre.
** Le débutant de Golang a besoin d'aide **
Voici le code de travail :
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() } }
Et commencez à diffuser :
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 } }
.
Cela a fonctionné pour moi, maintenant je ne trouve pas de meilleur moyen. Si quelqu'un a un meilleur moyen, veuillez commenter.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!