mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-10-05 08:16:55 +08:00
Add /api/ffmpeg for playing files and tts on cameras with two-way audio
This commit is contained in:
51
internal/ffmpeg/api.go
Normal file
51
internal/ffmpeg/api.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package ffmpeg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
|
)
|
||||||
|
|
||||||
|
func apiFFmpeg(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "POST" {
|
||||||
|
http.Error(w, "", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
query := r.URL.Query()
|
||||||
|
dst := query.Get("dst")
|
||||||
|
stream := streams.Get(dst)
|
||||||
|
if stream == nil {
|
||||||
|
http.Error(w, "", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var src string
|
||||||
|
if s := query.Get("file"); s != "" {
|
||||||
|
if streams.Validate(s) == nil {
|
||||||
|
src = "ffmpeg:" + s + "#audio=auto#input=file"
|
||||||
|
}
|
||||||
|
} else if s = query.Get("live"); s != "" {
|
||||||
|
if streams.Validate(s) == nil {
|
||||||
|
src = "ffmpeg:" + s + "#audio=auto"
|
||||||
|
}
|
||||||
|
} else if s = query.Get("text"); s != "" {
|
||||||
|
if strings.IndexAny(s, `'"&%$`) < 0 {
|
||||||
|
src = "ffmpeg:tts?text=" + s
|
||||||
|
if s = query.Get("voice"); s != "" {
|
||||||
|
src += "&voice=" + s
|
||||||
|
}
|
||||||
|
src += "#audio=auto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if src == "" {
|
||||||
|
http.Error(w, "", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := stream.Play(src); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
"github.com/AlexxIT/go2rtc/internal/app"
|
"github.com/AlexxIT/go2rtc/internal/app"
|
||||||
"github.com/AlexxIT/go2rtc/internal/ffmpeg/device"
|
"github.com/AlexxIT/go2rtc/internal/ffmpeg/device"
|
||||||
"github.com/AlexxIT/go2rtc/internal/ffmpeg/hardware"
|
"github.com/AlexxIT/go2rtc/internal/ffmpeg/hardware"
|
||||||
@@ -40,6 +41,8 @@ func Init() {
|
|||||||
|
|
||||||
streams.HandleFunc("ffmpeg", NewProducer)
|
streams.HandleFunc("ffmpeg", NewProducer)
|
||||||
|
|
||||||
|
api.HandleFunc("api/ffmpeg", apiFFmpeg)
|
||||||
|
|
||||||
device.Init(defaults["bin"])
|
device.Init(defaults["bin"])
|
||||||
hardware.Init(defaults["bin"])
|
hardware.Init(defaults["bin"])
|
||||||
}
|
}
|
||||||
|
@@ -85,16 +85,21 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2>Play audio</h2>
|
<h2>Play audio</h2>
|
||||||
<pre>example: ffmpeg:https://example.com/song.mp3#audio=pcma#input=file</pre>
|
<label><input type="radio" name="play" value="file" checked>file - play remote (https://example.com/song.mp3) or local (/media/song.mp3) file</label><br>
|
||||||
<input id="play-url" type="text" placeholder="url">
|
<label><input type="radio" name="play" value="live">live - play remote live stream (radio, etc.)</label><br>
|
||||||
|
<label><input type="radio" name="play" value="text">text - play Text To Speech (if your FFmpeg support this)</label><br>
|
||||||
|
<br>
|
||||||
|
<input id="play-url" type="text" placeholder="path / url / text">
|
||||||
<a id="play-send" href="#">send</a> / cameras with two way audio support
|
<a id="play-send" href="#">send</a> / cameras with two way audio support
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById('play-send').addEventListener('click', ev => {
|
document.getElementById('play-send').addEventListener('click', ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
const url = new URL('api/streams', location.href);
|
// action - file / live / text
|
||||||
|
const action = document.querySelector('input[name="play"]:checked').value;
|
||||||
|
const url = new URL('api/ffmpeg', location.href);
|
||||||
url.searchParams.set('dst', src);
|
url.searchParams.set('dst', src);
|
||||||
url.searchParams.set('src', document.getElementById('play-url').value);
|
url.searchParams.set(action, document.getElementById('play-url').value);
|
||||||
fetch(url, {method: 'POST'});
|
fetch(url, {method: 'POST'});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
Reference in New Issue
Block a user