arut / nginx-rtmp-module

NGINX-based Media Streaming Server

Home Page:http://nginx-rtmp.blogspot.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Difference between on_play and on_publish

narayanan-ka opened this issue · comments

commented

I can't understand the difference between on_play and on_publish. Can @arut please explain to me in simple terms ?Your response would be helpful. I can't understand which one to use.

My use case is : Have a django api server for authentication and I intend to use the nginx rtmp module for live streaming and video on demand. For live, i'm currently using the on_publish and on_publish_done which point to 2 functions on my django end to invoke a start a stream and stop a stream. However, For VOD, however, I need to allow the user to upload the file first to nginx after clicking upload and then nginx handles the processing and playing. Can I use the same 2 on_publish and on_publish_done to accept an upload from django end inside the rtmp block.

I have something like this :

    application vod {
        # Live status
        live off;

        # disable consuming the stream from nginx as rtmp
        deny play all;

        # Push the video stream to the local vod application for playing flv's
        push rtmp://www.mydomain.come:4935/vod-flv/;

        # Make HTTP request & use HTTP retcode
        # to decide whether to allow publishing
        # from this connection or not
        # The on_publish callback will redirect the RTMP stream to the streamer's username, rather than their secret stream key
        on_publish      http://www.mydomain.come:80/my-api/vod/startstream/;

        on_publish_dcome http://www.mydomain.come:80/my-api/vod/stopstream/;
    }

    application vod-flv {
        live off;
        # Only accept publishing from localhost.
        # (the `app` RTMP ingest application)
        allow publish www.mydomain.come;

        # play /opt/data/vod-flv/;
        flv_path  /opt/data/vod-flv/;

        allow publish all;

        allow play all;

        Use FLV encryption
        flv_keys on;
        flv_key_path /opt/data/keys/flv;
        flv_fragments_per_key 6;
        flv_key_url /keys/flv/;
    }

With on_publish you can forward the on publish request to a server. I use it to allow users to use the same streamkey but redirect to another application with the name set to the actual uuid of the individual stream I want to begin.

That is my workflow. on_play I havent used. Maybe someone else has a better explanation.

See my example go server:

func main() {
       go serverStreamingServer()
}

func serveStreamingServer() *http.Server {
	http.HandleFunc("/stream/publish", handleIngestLiveStreamPublishAuthentication)
	log.Printf("Media Compliant Server listening at %v", streamingServicesPort)
	err := http.ListenAndServe(serviceAddress+streamingServicesPort, nil)
	if err != nil {
		log.Fatalf("Failed to run Media Compliant Server: %v", err)
	}
	return &http.Server{}
}
func handleIngestLiveStreamPublishAuthentication(w http.ResponseWriter, r *http.Request) {
	log.Println("Received Publish request at /stream/publish")
	body, err := io.ReadAll(r.Body)
	if err != nil {
		// Handle error
		log.Println("Error reading request body:", err)
		http.Error(w, "Error reading request body", http.StatusInternalServerError)
		return
	}

	query, err := url.ParseQuery(string(body))
	if err != nil {
		log.Println("Error parsing query string:", err)
		http.Error(w, "Error parsing query string", http.StatusInternalServerError)
		return
	}

	// Get the value of the "name" field
	streamKey := query.Get("name")
	if streamKey == "" {
		log.Println("Name field is missing")
		http.Error(w, "Name field is missing", http.StatusBadRequest)
		return
	}

	// Check if the stream key is valid or authorized
	if isValidStreamKey(streamKey) == true {
                // based on stream key get application and name of stream
		redirectStreamUrl := streamingServer + "/hls_" + application + "/" + name
		w.Header().Set("Location", redirectStreamUrl)
		w.WriteHeader(http.StatusFound)
		return
	}
	// Send an error response for invalid or unauthorized stream key
	w.WriteHeader(http.StatusForbidden)
	fmt.Fprint(w, "Stream denied")
	return
}

Took me a while to figure this out. Its primarily for a use case in which I can handle authentication and setting of stream id/pathing without having user change their streamkey ever.

Redirect it back to your nginx but to another application that actually ingests stream. Otherwise, I dont think you need to use on_publish if you dont have any sort of ceremony your streaming solution needs to do.

My understanding of on_publish_done is that fires when the stream has ended. So when the stream is complete and you have business logic for complete streams you should use that.

commented

@lovgrandma Sorry for reverting late. Got lost in the list of notifications on Git. I did exactly Already what you have done for on_publish and on_publish done. I still cant wrap my head around on_play and on_play done. Form the directives listed here https://github.com/arut/nginx-rtmp-module/wiki/Directives#on_publish
It seems on_publish is for remote push while on_play for remote_pull. Only if we know what both terms mean from a workflow perspective ?