From 0ee848edfedd33d853cd0cdbbcdc0dc35c7d2e67 Mon Sep 17 00:00:00 2001 From: Rob Emery Date: Mon, 3 Feb 2025 16:21:52 +0000 Subject: [PATCH] Moving direct file access under /r/f/ so we can add /r/s/ for streaming --- dlna/contenddirectoryservice.go | 8 ++--- dlna/dlnaserver.go | 63 +++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 30 deletions(-) diff --git a/dlna/contenddirectoryservice.go b/dlna/contenddirectoryservice.go index 509ad6dbf..850ca68ad 100644 --- a/dlna/contenddirectoryservice.go +++ b/dlna/contenddirectoryservice.go @@ -84,7 +84,7 @@ func (cds *contentDirectoryService) cdsObjectToUpnpavObject(cdsObject object, is URL: (&url.URL{ Scheme: "http", Host: host, - Path: path.Join(resourcePath, cdsObject.Path), + Path: path.Join(resourcePath, resourceFilePath, cdsObject.Path), }).String(), ProtocolInfo: fmt.Sprintf("http-get:*:%s:%s", mimeType, dlna.ContentFeatures{ SupportRange: true, @@ -285,13 +285,13 @@ func (cds *contentDirectoryService) doMediaFiles(tracks model.MediaFiles, basePa } //TODO replace this with a streaming path - directFileAccessPath := path.Join(resourcePath, strings.TrimPrefix(track.Path, conf.Server.MusicFolder)) - + //directFileAccessPath := path.Join(resourcePath, resourceFilePath, "Music/Files", strings.TrimPrefix(track.Path, conf.Server.MusicFolder)) + streamAccessPath := path.Join(resourcePath, resourceStreamPath, track.ID) item.Res = append(item.Res, upnpav.Resource{ URL: (&url.URL{ Scheme: "http", Host: host, - Path: directFileAccessPath, + Path: streamAccessPath, }).String(), ProtocolInfo: fmt.Sprintf("http-get:*:%s:%s", mimeType, dlna.ContentFeatures{ SupportRange: false, diff --git a/dlna/dlnaserver.go b/dlna/dlnaserver.go index 52c35fac3..7fe4de6d3 100644 --- a/dlna/dlnaserver.go +++ b/dlna/dlnaserver.go @@ -33,6 +33,8 @@ const ( serverField = "Linux/3.4 DLNADOC/1.50 UPnP/1.0 DMS/1.0" rootDescPath = "/rootDesc.xml" resourcePath = "/r/" + resourceFilePath = "f" + resourceStreamPath = "s" serviceControlURL = "/ctl" ) @@ -275,35 +277,44 @@ func isAppropriatelyConfigured(intf net.Interface) bool { func (s *SSDPServer) resourceHandler(w http.ResponseWriter, r *http.Request) { remotePath := r.URL.Path - localFile, _ := strings.CutPrefix(remotePath, "Music/Files/") - localFilePath := path.Join(conf.Server.MusicFolder, localFile) + components := strings.Split(remotePath, "/") + switch components[0] { + case resourceFilePath: + localFile, _ := strings.CutPrefix(remotePath, path.Join(resourceFilePath,"Music/Files")) + localFilePath := path.Join(conf.Server.MusicFolder, localFile) - log.Info(fmt.Sprintf("resource handler Executed with remote path: %s, localpath: %s", remotePath, localFilePath)) + log.Info(fmt.Sprintf("resource handler Executed with remote path: %s, localpath: %s", remotePath, localFilePath)) - fileStats, err := os.Stat(localFilePath) - if err != nil { - http.NotFound(w, r) - return + fileStats, err := os.Stat(localFilePath) + if err != nil { + http.NotFound(w, r) + return + } + w.Header().Set("Content-Length", strconv.FormatInt(fileStats.Size(), 10)) + + // add some DLNA specific headers + if r.Header.Get("getContentFeatures.dlna.org") != "" { + w.Header().Set("contentFeatures.dlna.org", dms_dlna.ContentFeatures{ + SupportRange: true, + }.String()) + } + w.Header().Set("transferMode.dlna.org", "Streaming") + + os.Open(localFilePath) + fileHandle, err := os.Open(localFilePath) + if err != nil { + fmt.Printf("file streaming error: %+v\n", err) + return + } + defer fileHandle.Close() + + http.ServeContent(w, r, remotePath, time.Now(), fileHandle) + break; + case resourceStreamPath: + //TODO streaming endpoint + log.Debug(fmt.Sprintf("TODO IMPLEMENT THIS: %+v", r)) + break; } - w.Header().Set("Content-Length", strconv.FormatInt(fileStats.Size(), 10)) - - // add some DLNA specific headers - if r.Header.Get("getContentFeatures.dlna.org") != "" { - w.Header().Set("contentFeatures.dlna.org", dms_dlna.ContentFeatures{ - SupportRange: true, - }.String()) - } - w.Header().Set("transferMode.dlna.org", "Streaming") - - os.Open(localFilePath) - fileHandle, err := os.Open(localFilePath) - if err != nil { - fmt.Printf("file streaming error: %+v\n", err) - return - } - defer fileHandle.Close() - - http.ServeContent(w, r, remotePath, time.Now(), fileHandle) } // returns /rootDesc.xml templated