bluenviron / mediamtx

Ready-to-use SRT / WebRTC / RTSP / RTMP / LL-HLS media server and media proxy that allows to read, publish, proxy, record and playback video and audio streams.
MIT License
10.71k stars 1.4k forks source link

Add stream details for ready to start hook #3516

Open ditogam opened 3 days ago

ditogam commented 3 days ago

Describe the feature

It would be nice to have stream info for runOnReady, so we can construct propper command based on input info. For example: If source video codec is already H264, but audio codec is AAC, we can construct ffmpeg like: ffmpeg -i "srt://localhost:8890?streamid=read:$RTSP_PATH" -c:v copy -c:a libopus -b:a 256k -f mpegts "srt://localhost:8890?streamid=publish:webrtc_$RTSP_PATH"

If source video codec is already H264, and audio codec is already Opus, we can construct ffmpeg like: ffmpeg -i "srt://localhost:8890?streamid=read:$RTSP_PATH" -c copy -f mpegts "srt://localhost:8890?streamid=publish:webrtc_$RTSP_PATH"

Or dynamically construct gstreamer pipeline

Here is little idea. Putting codec info by format and RTPMap/FMTPMap for additional info like SampleRate, ChannelCount and so on

Subject: [PATCH] mediamtx
---
Index: internal/core/path.go
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/internal/core/path.go b/internal/core/path.go
--- a/internal/core/path.go (revision a1dc9f45f5e2a03084274bea139ecaa2e805d659)
+++ b/internal/core/path.go (date 1719673626662)
@@ -2,6 +2,8 @@

 import (
    "context"
+   "encoding/base64"
+   "encoding/json"
    "fmt"
    "net"
    "strconv"
@@ -623,6 +625,39 @@
    return pa.conf
 }

+func (pa *path) ExternalCmdEnvFromSession(desc *description.Session) externalcmd.Environment {
+   env := pa.ExternalCmdEnv()
+
+   if desc != nil {
+       if desc.BaseURL != nil {
+           env["MTX_BASE_URL"] = desc.BaseURL.String()
+       }
+
+       env["MTX_TITLE"] = desc.Title
+
+       for _, media := range desc.Medias {
+           envNamePrefix := "MTX_MEDIA_TYPE_" + strings.ToUpper(string(media.Type))
+           if len(media.Formats) == 1 {
+               format := media.Formats[0]
+               env[envNamePrefix+"_CODEC"] = format.Codec()
+               env[envNamePrefix+"_CLOCK_RATE"] = strconv.Itoa(format.ClockRate())
+               env[envNamePrefix+"_RTP_MAP"] = format.RTPMap()
+
+               fmtp := format.FMTP()
+               if fmtp != nil {
+                   jsonData, err := json.Marshal(fmtp)
+                   if err == nil {
+                       env[envNamePrefix+"_FMTP_MAP_JSON_BASE64"] = base64.StdEncoding.EncodeToString(jsonData)
+                   }
+               }
+           }
+
+       }
+   }
+
+   return env
+}
+
 func (pa *path) ExternalCmdEnv() externalcmd.Environment {
    _, port, _ := net.SplitHostPort(pa.rtspAddress)
    env := externalcmd.Environment{
@@ -731,7 +766,7 @@
        Logger:          pa,
        ExternalCmdPool: pa.externalCmdPool,
        Conf:            pa.conf,
-       ExternalCmdEnv:  pa.ExternalCmdEnv(),
+       ExternalCmdEnv:  pa.ExternalCmdEnvFromSession(desc),
        Desc:            pa.source.APISourceDescribe(),
        Query:           pa.publisherQuery,
    })