Difference between on_play and on_publish
narayanan-ka opened this issue · comments
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.
@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 ?