mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-09-27 04:36:12 +08:00
Rename streams to sources in the discovery API
This commit is contained in:
@@ -213,21 +213,23 @@ func exitHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
os.Exit(code)
|
os.Exit(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stream struct {
|
type Source struct {
|
||||||
Name string `json:"name"`
|
ID string `json:"id,omitempty"`
|
||||||
URL string `json:"url"`
|
Name string `json:"name,omitempty"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Location string `json:"location,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResponseStreams(w http.ResponseWriter, streams []Stream) {
|
func ResponseSources(w http.ResponseWriter, sources []Source) {
|
||||||
if len(streams) == 0 {
|
if len(sources) == 0 {
|
||||||
http.Error(w, "no streams", http.StatusNotFound)
|
http.Error(w, "no sources", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = struct {
|
var response = struct {
|
||||||
Streams []Stream `json:"streams"`
|
Sources []Source `json:"sources"`
|
||||||
}{
|
}{
|
||||||
Streams: streams,
|
Sources: sources,
|
||||||
}
|
}
|
||||||
ResponseJSON(w, response)
|
ResponseJSON(w, response)
|
||||||
}
|
}
|
||||||
|
@@ -45,10 +45,10 @@ func apiDvrip(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
api.ResponseStreams(w, items)
|
api.ResponseSources(w, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
func discover() ([]api.Stream, error) {
|
func discover() ([]api.Source, error) {
|
||||||
addr := &net.UDPAddr{
|
addr := &net.UDPAddr{
|
||||||
Port: Port,
|
Port: Port,
|
||||||
IP: net.IP{239, 255, 255, 250},
|
IP: net.IP{239, 255, 255, 250},
|
||||||
@@ -63,7 +63,7 @@ func discover() ([]api.Stream, error) {
|
|||||||
|
|
||||||
go sendBroadcasts(conn)
|
go sendBroadcasts(conn)
|
||||||
|
|
||||||
var items []api.Stream
|
var items []api.Source
|
||||||
|
|
||||||
for _, info := range getResponses(conn) {
|
for _, info := range getResponses(conn) {
|
||||||
if info.HostIP == "" || info.HostName == "" {
|
if info.HostIP == "" || info.HostName == "" {
|
||||||
@@ -75,7 +75,7 @@ func discover() ([]api.Stream, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
items = append(items, api.Stream{
|
items = append(items, api.Source{
|
||||||
Name: info.HostName,
|
Name: info.HostName,
|
||||||
URL: "dvrip://user:pass@" + host + "?channel=0&subtype=0",
|
URL: "dvrip://user:pass@" + host + "?channel=0&subtype=0",
|
||||||
})
|
})
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
package device
|
package device
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func queryToInput(query url.Values) string {
|
func queryToInput(query url.Values) string {
|
||||||
@@ -78,7 +79,7 @@ func initDevices() {
|
|||||||
audios = append(audios, name)
|
audios = append(audios, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
streams = append(streams, api.Stream{
|
streams = append(streams, api.Source{
|
||||||
Name: name, URL: "ffmpeg:device?" + kind + "=" + name,
|
Name: name, URL: "ffmpeg:device?" + kind + "=" + name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -70,7 +70,7 @@ func initDevices() {
|
|||||||
m := re.FindAllStringSubmatch(string(b), -1)
|
m := re.FindAllStringSubmatch(string(b), -1)
|
||||||
for _, i := range m {
|
for _, i := range m {
|
||||||
size, _, _ := strings.Cut(i[4], " ")
|
size, _, _ := strings.Cut(i[4], " ")
|
||||||
stream := api.Stream{
|
stream := api.Source{
|
||||||
Name: i[3] + " | " + i[4],
|
Name: i[3] + " | " + i[4],
|
||||||
URL: "ffmpeg:device?video=" + name + "&input_format=" + i[2] + "&video_size=" + size,
|
URL: "ffmpeg:device?video=" + name + "&input_format=" + i[2] + "&video_size=" + size,
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ func initDevices() {
|
|||||||
|
|
||||||
err = exec.Command(Bin, "-f", "alsa", "-i", "default", "-t", "1", "-f", "null", "-").Run()
|
err = exec.Command(Bin, "-f", "alsa", "-i", "default", "-t", "1", "-f", "null", "-").Run()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
stream := api.Stream{
|
stream := api.Source{
|
||||||
Name: "ALSA default",
|
Name: "ALSA default",
|
||||||
URL: "ffmpeg:device?audio=default&channels=1&sample_rate=16000&#audio=opus",
|
URL: "ffmpeg:device?audio=default&channels=1&sample_rate=16000&#audio=opus",
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
package device
|
package device
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func queryToInput(query url.Values) string {
|
func queryToInput(query url.Values) string {
|
||||||
@@ -79,7 +80,7 @@ func initDevices() {
|
|||||||
name := m[1]
|
name := m[1]
|
||||||
kind := m[2]
|
kind := m[2]
|
||||||
|
|
||||||
stream := api.Stream{
|
stream := api.Source{
|
||||||
Name: name, URL: "ffmpeg:device?" + kind + "=" + name,
|
Name: name, URL: "ffmpeg:device?" + kind + "=" + name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,12 +2,13 @@ package device
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init(bin string) {
|
func Init(bin string) {
|
||||||
@@ -39,13 +40,13 @@ func GetInput(src string) (string, error) {
|
|||||||
var Bin string
|
var Bin string
|
||||||
|
|
||||||
var videos, audios []string
|
var videos, audios []string
|
||||||
var streams []api.Stream
|
var streams []api.Source
|
||||||
var runonce sync.Once
|
var runonce sync.Once
|
||||||
|
|
||||||
func apiDevices(w http.ResponseWriter, r *http.Request) {
|
func apiDevices(w http.ResponseWriter, r *http.Request) {
|
||||||
runonce.Do(initDevices)
|
runonce.Do(initDevices)
|
||||||
|
|
||||||
api.ResponseStreams(w, streams)
|
api.ResponseSources(w, streams)
|
||||||
}
|
}
|
||||||
|
|
||||||
func indexToItem(items []string, index string) string {
|
func indexToItem(items []string, index string) string {
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
package hardware
|
package hardware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/ffmpeg"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ const (
|
|||||||
|
|
||||||
func Init(bin string) {
|
func Init(bin string) {
|
||||||
api.HandleFunc("api/ffmpeg/hardware", func(w http.ResponseWriter, r *http.Request) {
|
api.HandleFunc("api/ffmpeg/hardware", func(w http.ResponseWriter, r *http.Request) {
|
||||||
api.ResponseStreams(w, ProbeAll(bin))
|
api.ResponseSources(w, ProbeAll(bin))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,8 +7,8 @@ import (
|
|||||||
const ProbeVideoToolboxH264 = "-f lavfi -i testsrc2=size=svga -t 1 -c h264_videotoolbox -f null -"
|
const ProbeVideoToolboxH264 = "-f lavfi -i testsrc2=size=svga -t 1 -c h264_videotoolbox -f null -"
|
||||||
const ProbeVideoToolboxH265 = "-f lavfi -i testsrc2=size=svga -t 1 -c hevc_videotoolbox -f null -"
|
const ProbeVideoToolboxH265 = "-f lavfi -i testsrc2=size=svga -t 1 -c hevc_videotoolbox -f null -"
|
||||||
|
|
||||||
func ProbeAll(bin string) []api.Stream {
|
func ProbeAll(bin string) []api.Source {
|
||||||
return []api.Stream{
|
return []api.Source{
|
||||||
{
|
{
|
||||||
Name: runToString(bin, ProbeVideoToolboxH264),
|
Name: runToString(bin, ProbeVideoToolboxH264),
|
||||||
URL: "ffmpeg:...#video=h264#hardware=" + EngineVideoToolbox,
|
URL: "ffmpeg:...#video=h264#hardware=" + EngineVideoToolbox,
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
package hardware
|
package hardware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
const ProbeV4L2M2MH264 = "-f lavfi -i testsrc2 -t 1 -c h264_v4l2m2m -f null -"
|
const ProbeV4L2M2MH264 = "-f lavfi -i testsrc2 -t 1 -c h264_v4l2m2m -f null -"
|
||||||
@@ -13,9 +14,9 @@ const ProbeVAAPIJPEG = "-init_hw_device vaapi -f lavfi -i testsrc2 -t 1 -vf form
|
|||||||
const ProbeCUDAH264 = "-init_hw_device cuda -f lavfi -i testsrc2 -t 1 -c h264_nvenc -f null -"
|
const ProbeCUDAH264 = "-init_hw_device cuda -f lavfi -i testsrc2 -t 1 -c h264_nvenc -f null -"
|
||||||
const ProbeCUDAH265 = "-init_hw_device cuda -f lavfi -i testsrc2 -t 1 -c hevc_nvenc -f null -"
|
const ProbeCUDAH265 = "-init_hw_device cuda -f lavfi -i testsrc2 -t 1 -c hevc_nvenc -f null -"
|
||||||
|
|
||||||
func ProbeAll(bin string) []api.Stream {
|
func ProbeAll(bin string) []api.Source {
|
||||||
if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" {
|
if runtime.GOARCH == "arm64" || runtime.GOARCH == "arm" {
|
||||||
return []api.Stream{
|
return []api.Source{
|
||||||
{
|
{
|
||||||
Name: runToString(bin, ProbeV4L2M2MH264),
|
Name: runToString(bin, ProbeV4L2M2MH264),
|
||||||
URL: "ffmpeg:...#video=h264#hardware=" + EngineV4L2M2M,
|
URL: "ffmpeg:...#video=h264#hardware=" + EngineV4L2M2M,
|
||||||
@@ -27,7 +28,7 @@ func ProbeAll(bin string) []api.Stream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return []api.Stream{
|
return []api.Source{
|
||||||
{
|
{
|
||||||
Name: runToString(bin, ProbeVAAPIH264),
|
Name: runToString(bin, ProbeVAAPIH264),
|
||||||
URL: "ffmpeg:...#video=h264#hardware=" + EngineVAAPI,
|
URL: "ffmpeg:...#video=h264#hardware=" + EngineVAAPI,
|
||||||
|
@@ -8,8 +8,8 @@ const ProbeDXVA2JPEG = "-init_hw_device dxva2 -f lavfi -i testsrc2 -t 1 -c mjpeg
|
|||||||
const ProbeCUDAH264 = "-init_hw_device cuda -f lavfi -i testsrc2 -t 1 -c h264_nvenc -f null -"
|
const ProbeCUDAH264 = "-init_hw_device cuda -f lavfi -i testsrc2 -t 1 -c h264_nvenc -f null -"
|
||||||
const ProbeCUDAH265 = "-init_hw_device cuda -f lavfi -i testsrc2 -t 1 -c hevc_nvenc -f null -"
|
const ProbeCUDAH265 = "-init_hw_device cuda -f lavfi -i testsrc2 -t 1 -c hevc_nvenc -f null -"
|
||||||
|
|
||||||
func ProbeAll(bin string) []api.Stream {
|
func ProbeAll(bin string) []api.Source {
|
||||||
return []api.Stream{
|
return []api.Source{
|
||||||
{
|
{
|
||||||
Name: runToString(bin, ProbeDXVA2H264),
|
Name: runToString(bin, ProbeDXVA2H264),
|
||||||
URL: "ffmpeg:...#video=h264#hardware=" + EngineDXVA2,
|
URL: "ffmpeg:...#video=h264#hardware=" + EngineDXVA2,
|
||||||
|
@@ -72,11 +72,13 @@ func Init() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
var items []api.Stream
|
var items []api.Source
|
||||||
for name, url := range entities {
|
for name, url := range entities {
|
||||||
items = append(items, api.Stream{Name: name, URL: url})
|
items = append(items, api.Source{
|
||||||
|
Name: name, URL: "hass:" + name, Location: url,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
api.ResponseStreams(w, items)
|
api.ResponseSources(w, items)
|
||||||
})
|
})
|
||||||
|
|
||||||
// for Addon listen on hassio interface, so WebUI feature will work
|
// for Addon listen on hassio interface, so WebUI feature will work
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
package nest
|
package nest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/nest"
|
"github.com/AlexxIT/go2rtc/pkg/nest"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -41,15 +42,15 @@ func apiNest(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var items []api.Stream
|
var items []api.Source
|
||||||
|
|
||||||
for name, deviceID := range devices {
|
for name, deviceID := range devices {
|
||||||
query.Set("device_id", deviceID)
|
query.Set("device_id", deviceID)
|
||||||
|
|
||||||
items = append(items, api.Stream{
|
items = append(items, api.Source{
|
||||||
Name: name, URL: "nest:?" + query.Encode(),
|
Name: name, URL: "nest:?" + query.Encode(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
api.ResponseStreams(w, items)
|
api.ResponseSources(w, items)
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,6 @@
|
|||||||
package onvif
|
package onvif
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/app"
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/rtsp"
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/onvif"
|
|
||||||
"github.com/rs/zerolog"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -15,6 +8,14 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/app"
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/rtsp"
|
||||||
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
|
"github.com/AlexxIT/go2rtc/pkg/onvif"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -121,7 +122,7 @@ func onvifDeviceService(w http.ResponseWriter, r *http.Request) {
|
|||||||
func apiOnvif(w http.ResponseWriter, r *http.Request) {
|
func apiOnvif(w http.ResponseWriter, r *http.Request) {
|
||||||
src := r.URL.Query().Get("src")
|
src := r.URL.Query().Get("src")
|
||||||
|
|
||||||
var items []api.Stream
|
var items []api.Source
|
||||||
|
|
||||||
if src == "" {
|
if src == "" {
|
||||||
urls, err := onvif.DiscoveryStreamingURLs()
|
urls, err := onvif.DiscoveryStreamingURLs()
|
||||||
@@ -149,7 +150,7 @@ func apiOnvif(w http.ResponseWriter, r *http.Request) {
|
|||||||
u.Path = ""
|
u.Path = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
items = append(items, api.Stream{Name: u.Host, URL: u.String()})
|
items = append(items, api.Source{Name: u.Host, URL: u.String()})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
client, err := onvif.NewClient(src)
|
client, err := onvif.NewClient(src)
|
||||||
@@ -176,19 +177,19 @@ func apiOnvif(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, token := range tokens {
|
for i, token := range tokens {
|
||||||
items = append(items, api.Stream{
|
items = append(items, api.Source{
|
||||||
Name: name + " stream" + strconv.Itoa(i),
|
Name: name + " stream" + strconv.Itoa(i),
|
||||||
URL: src + "?subtype=" + token,
|
URL: src + "?subtype=" + token,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tokens) > 0 && client.HasSnapshots() {
|
if len(tokens) > 0 && client.HasSnapshots() {
|
||||||
items = append(items, api.Stream{
|
items = append(items, api.Source{
|
||||||
Name: name + " snapshot",
|
Name: name + " snapshot",
|
||||||
URL: src + "?subtype=" + tokens[0] + "&snapshot",
|
URL: src + "?subtype=" + tokens[0] + "&snapshot",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
api.ResponseStreams(w, items)
|
api.ResponseSources(w, items)
|
||||||
}
|
}
|
||||||
|
@@ -2,11 +2,12 @@ package roborock
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/roborock"
|
"github.com/AlexxIT/go2rtc/pkg/roborock"
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -84,7 +85,7 @@ func apiHandle(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var items []api.Stream
|
var items []api.Source
|
||||||
|
|
||||||
for _, device := range devices {
|
for _, device := range devices {
|
||||||
source := fmt.Sprintf(
|
source := fmt.Sprintf(
|
||||||
@@ -93,8 +94,8 @@ func apiHandle(w http.ResponseWriter, r *http.Request) {
|
|||||||
Auth.UserData.IoT.User, Auth.UserData.IoT.Pass, Auth.UserData.IoT.Domain,
|
Auth.UserData.IoT.User, Auth.UserData.IoT.Pass, Auth.UserData.IoT.Domain,
|
||||||
device.DID, device.Key,
|
device.DID, device.Key,
|
||||||
)
|
)
|
||||||
items = append(items, api.Stream{Name: device.Name, URL: source})
|
items = append(items, api.Source{Name: device.Name, URL: source})
|
||||||
}
|
}
|
||||||
|
|
||||||
api.ResponseStreams(w, items)
|
api.ResponseSources(w, items)
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,9 @@ package webtorrent
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/internal/api"
|
"github.com/AlexxIT/go2rtc/internal/api"
|
||||||
"github.com/AlexxIT/go2rtc/internal/app"
|
"github.com/AlexxIT/go2rtc/internal/app"
|
||||||
"github.com/AlexxIT/go2rtc/internal/streams"
|
"github.com/AlexxIT/go2rtc/internal/streams"
|
||||||
@@ -10,8 +13,6 @@ import (
|
|||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
"github.com/AlexxIT/go2rtc/pkg/webtorrent"
|
"github.com/AlexxIT/go2rtc/pkg/webtorrent"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@@ -110,13 +111,13 @@ func apiHandle(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// response all shares
|
// response all shares
|
||||||
var items []api.Stream
|
var items []api.Source
|
||||||
for src, share := range shares {
|
for src, share := range shares {
|
||||||
pwd := srv.GetSharePwd(share)
|
pwd := srv.GetSharePwd(share)
|
||||||
source := fmt.Sprintf("webtorrent:?share=%s&pwd=%s", share, pwd)
|
source := fmt.Sprintf("webtorrent:?share=%s&pwd=%s", share, pwd)
|
||||||
items = append(items, api.Stream{Name: src, URL: source})
|
items = append(items, api.Source{ID: src, URL: source})
|
||||||
}
|
}
|
||||||
api.ResponseStreams(w, items)
|
api.ResponseSources(w, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "POST":
|
case "POST":
|
||||||
|
35
www/add.html
35
www/add.html
@@ -59,7 +59,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<script src="main.js"></script>
|
<script src="main.js"></script>
|
||||||
<script>
|
<script>
|
||||||
async function getStreams(url, tableID) {
|
async function getSources(url, tableID) {
|
||||||
const table = document.getElementById(tableID);
|
const table = document.getElementById(tableID);
|
||||||
table.innerText = 'loading...';
|
table.innerText = 'loading...';
|
||||||
|
|
||||||
@@ -69,11 +69,16 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {{streams:Array<{name:string,url:string}>}} */
|
const td = value => value ? `<td>${value}</td>` : '';
|
||||||
|
const th = (name, value) => value ? `<th>${name}</th>` : '';
|
||||||
|
|
||||||
|
/** @type {{sources:Array<{id:string,name:string,url:string,location:string}>}} */
|
||||||
const data = await r.json();
|
const data = await r.json();
|
||||||
table.innerHTML = data.streams.reduce((html, item) => {
|
const i0 = data.sources[0];
|
||||||
return html + `<tr><td>${item.name}</td><td>${item.url}</td></tr>`;
|
const thead = `<tr>${th('ID', i0.id)}${th('Name', i0.name)}${th('URL', i0.url)}${th('Location', i0.location)}</tr>`;
|
||||||
}, '<thead><tr><th>Name</th><th>Source</th></tr></thead><tbody>') + '</tbody>';
|
table.innerHTML = data.sources.reduce((html, item) => {
|
||||||
|
return `${html}<tr>${td(item.id)}${td(item.name)}${td(item.url)}${td(item.location)}</tr>`;
|
||||||
|
}, `<thead>${thead}</thead><tbody>`) + '</tbody>';
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -179,7 +184,7 @@
|
|||||||
<script>
|
<script>
|
||||||
document.getElementById('dvrip').addEventListener('click', async ev => {
|
document.getElementById('dvrip').addEventListener('click', async ev => {
|
||||||
ev.target.nextElementSibling.style.display = 'block';
|
ev.target.nextElementSibling.style.display = 'block';
|
||||||
await getStreams('api/dvrip', 'dvrip-table');
|
await getSources('api/dvrip', 'dvrip-table');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -192,7 +197,7 @@
|
|||||||
<script>
|
<script>
|
||||||
document.getElementById('devices').addEventListener('click', async ev => {
|
document.getElementById('devices').addEventListener('click', async ev => {
|
||||||
ev.target.nextElementSibling.style.display = 'block';
|
ev.target.nextElementSibling.style.display = 'block';
|
||||||
await getStreams('api/ffmpeg/devices', 'devices-table');
|
await getSources('api/ffmpeg/devices', 'devices-table');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -205,7 +210,7 @@
|
|||||||
<script>
|
<script>
|
||||||
document.getElementById('hardware').addEventListener('click', async ev => {
|
document.getElementById('hardware').addEventListener('click', async ev => {
|
||||||
ev.target.nextElementSibling.style.display = 'block';
|
ev.target.nextElementSibling.style.display = 'block';
|
||||||
await getStreams('api/ffmpeg/hardware', 'hardware-table');
|
await getSources('api/ffmpeg/hardware', 'hardware-table');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -234,7 +239,7 @@
|
|||||||
const url = new URL('api/nest?' + query.toString(), location.href);
|
const url = new URL('api/nest?' + query.toString(), location.href);
|
||||||
|
|
||||||
const r = await fetch(url, {cache: 'no-cache'});
|
const r = await fetch(url, {cache: 'no-cache'});
|
||||||
await getStreams(r, 'nest-table');
|
await getSources(r, 'nest-table');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -246,7 +251,7 @@
|
|||||||
<script>
|
<script>
|
||||||
document.getElementById('hass').addEventListener('click', async ev => {
|
document.getElementById('hass').addEventListener('click', async ev => {
|
||||||
ev.target.nextElementSibling.style.display = 'block';
|
ev.target.nextElementSibling.style.display = 'block';
|
||||||
await getStreams('api/hass', 'hass-table');
|
await getSources('api/hass', 'hass-table');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -262,7 +267,7 @@
|
|||||||
<script>
|
<script>
|
||||||
document.getElementById('onvif').addEventListener('click', async ev => {
|
document.getElementById('onvif').addEventListener('click', async ev => {
|
||||||
ev.target.nextElementSibling.style.display = 'block';
|
ev.target.nextElementSibling.style.display = 'block';
|
||||||
await getStreams('api/onvif', 'onvif-table');
|
await getSources('api/onvif', 'onvif-table');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('onvif-form').addEventListener('submit', async ev => {
|
document.getElementById('onvif-form').addEventListener('submit', async ev => {
|
||||||
@@ -271,7 +276,7 @@
|
|||||||
const url = new URL('api/onvif', location.href);
|
const url = new URL('api/onvif', location.href);
|
||||||
url.searchParams.set('src', ev.target.elements['src'].value);
|
url.searchParams.set('src', ev.target.elements['src'].value);
|
||||||
|
|
||||||
await getStreams(url.toString(), 'onvif-table');
|
await getSources(url.toString(), 'onvif-table');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -289,13 +294,13 @@
|
|||||||
<script>
|
<script>
|
||||||
document.getElementById('roborock').addEventListener('click', async ev => {
|
document.getElementById('roborock').addEventListener('click', async ev => {
|
||||||
ev.target.nextElementSibling.style.display = 'block';
|
ev.target.nextElementSibling.style.display = 'block';
|
||||||
await getStreams('api/roborock', 'roborock-table');
|
await getSources('api/roborock', 'roborock-table');
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('roborock-form').addEventListener('submit', async ev => {
|
document.getElementById('roborock-form').addEventListener('submit', async ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
const r = await fetch('api/roborock', {method: 'POST', body: new FormData(ev.target)});
|
const r = await fetch('api/roborock', {method: 'POST', body: new FormData(ev.target)});
|
||||||
await getStreams(r, 'roborock-table');
|
await getSources(r, 'roborock-table');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -307,7 +312,7 @@
|
|||||||
<script>
|
<script>
|
||||||
document.getElementById('webtorrent').addEventListener('click', async ev => {
|
document.getElementById('webtorrent').addEventListener('click', async ev => {
|
||||||
ev.target.nextElementSibling.style.display = 'block';
|
ev.target.nextElementSibling.style.display = 'block';
|
||||||
await getStreams('api/webtorrent', 'webtorrent-table');
|
await getSources('api/webtorrent', 'webtorrent-table');
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user