diff options
| author | Julian Hurst <julian.hurst@digdash.com> | 2024-09-10 16:00:53 +0200 |
|---|---|---|
| committer | Julian Hurst <julian.hurst@digdash.com> | 2024-09-10 16:00:53 +0200 |
| commit | 203810218b3285502d80127f4495c5383dc0c7c3 (patch) | |
| tree | a0914340bb097a3bf4741c5ca69550ac5cca6c11 | |
| download | ytstreamer-203810218b3285502d80127f4495c5383dc0c7c3.tar.gz | |
| -rw-r--r-- | go.mod | 3 | ||||
| -rw-r--r-- | ytstreamer.go | 73 |
2 files changed, 76 insertions, 0 deletions
@@ -0,0 +1,3 @@ +module ytstreamer + +go 1.19 diff --git a/ytstreamer.go b/ytstreamer.go new file mode 100644 index 0000000..5dd94b9 --- /dev/null +++ b/ytstreamer.go @@ -0,0 +1,73 @@ +package main + +import ( + "log" + "net/http" + "os/exec" + "io" + "strings" +) + +func combine(spl []string) (io.ReadCloser, error) { + cmd := exec.Command("ffmpeg", "-i", spl[0], "-i", spl[1], "-c:v", "copy", "-c:a", "copy", "-f", "matroska", "-") + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + if err := cmd.Start(); err != nil { + return nil, err + } + return stdout, nil +} + +func stream(w http.ResponseWriter, r *http.Request) { + values := r.URL.Query() + if !values.Has("yturl") { + w.WriteHeader(http.StatusBadRequest) + return + } + ytUrl := values.Get("yturl") + cmd := exec.Command("yt-dlp", "-g", ytUrl) + burls, err := cmd.Output() + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Println(err) + return + } + urls := string(burls) + urls = strings.Trim(urls, "\n") + log.Println(urls) + spl := strings.Split(urls, "\n") + log.Printf("spl: %d", len(spl)) + switch len(spl) { + case 1: + w.WriteHeader(http.StatusNoContent) + return + case 2: + stdout, err := combine(spl) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Println(err) + return + } + w.Header().Set("Content-Type", "video/mp4") + w.Header().Set("Connection", "keep-alive") + w.Header().Set("Transfer-Encoding", "chunked") + _, err = io.Copy(w, stdout) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + log.Println(err) + return + } + default: + w.WriteHeader(http.StatusBadRequest) + log.Println(err) + return + } +} + +func main() { + http.HandleFunc("/", stream) + + log.Fatal(http.ListenAndServe(":8080", nil)) +} |
