package handlers import ( "errors" "fmt" "seanime/internal/database/models" "seanime/internal/mediastream" "github.com/labstack/echo/v4" ) // HandleGetMediastreamSettings // // @summary get mediastream settings. // @desc This returns the mediastream settings. // @returns models.MediastreamSettings // @route /api/v1/mediastream/settings [GET] func (h *Handler) HandleGetMediastreamSettings(c echo.Context) error { mediastreamSettings, found := h.App.Database.GetMediastreamSettings() if !found { return h.RespondWithError(c, errors.New("media streaming settings not found")) } return h.RespondWithData(c, mediastreamSettings) } // HandleSaveMediastreamSettings // // @summary save mediastream settings. // @desc This saves the mediastream settings. // @returns models.MediastreamSettings // @route /api/v1/mediastream/settings [PATCH] func (h *Handler) HandleSaveMediastreamSettings(c echo.Context) error { type body struct { Settings models.MediastreamSettings `json:"settings"` } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } settings, err := h.App.Database.UpsertMediastreamSettings(&b.Settings) if err != nil { return h.RespondWithError(c, err) } h.App.InitOrRefreshMediastreamSettings() return h.RespondWithData(c, settings) } // HandleRequestMediastreamMediaContainer // // @summary request media stream. // @desc This requests a media stream and returns the media container to start the playback. // @returns mediastream.MediaContainer // @route /api/v1/mediastream/request [POST] func (h *Handler) HandleRequestMediastreamMediaContainer(c echo.Context) error { type body struct { Path string `json:"path"` // The path of the file. StreamType mediastream.StreamType `json:"streamType"` // The type of stream to request. AudioStreamIndex int `json:"audioStreamIndex"` // The audio stream index to use. (unused) ClientId string `json:"clientId"` // The session id } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } var mediaContainer *mediastream.MediaContainer var err error switch b.StreamType { case mediastream.StreamTypeDirect: mediaContainer, err = h.App.MediastreamRepository.RequestDirectPlay(b.Path, b.ClientId) case mediastream.StreamTypeTranscode: mediaContainer, err = h.App.MediastreamRepository.RequestTranscodeStream(b.Path, b.ClientId) case mediastream.StreamTypeOptimized: err = fmt.Errorf("stream type %s not implemented", b.StreamType) //mediaContainer, err = h.App.MediastreamRepository.RequestOptimizedStream(b.Path) default: err = fmt.Errorf("stream type %s not implemented", b.StreamType) } if err != nil { return h.RespondWithError(c, err) } return h.RespondWithData(c, mediaContainer) } // HandlePreloadMediastreamMediaContainer // // @summary preloads media stream for playback. // @desc This preloads a media stream by extracting the media information and attachments. // @returns bool // @route /api/v1/mediastream/preload [POST] func (h *Handler) HandlePreloadMediastreamMediaContainer(c echo.Context) error { type body struct { Path string `json:"path"` // The path of the file. StreamType mediastream.StreamType `json:"streamType"` // The type of stream to request. AudioStreamIndex int `json:"audioStreamIndex"` // The audio stream index to use. } var b body if err := c.Bind(&b); err != nil { return h.RespondWithError(c, err) } var err error switch b.StreamType { case mediastream.StreamTypeTranscode: err = h.App.MediastreamRepository.RequestPreloadTranscodeStream(b.Path) case mediastream.StreamTypeDirect: err = h.App.MediastreamRepository.RequestPreloadDirectPlay(b.Path) default: err = fmt.Errorf("stream type %s not implemented", b.StreamType) } if err != nil { return h.RespondWithError(c, err) } return h.RespondWithData(c, true) } func (h *Handler) HandleMediastreamGetSubtitles(c echo.Context) error { return h.App.MediastreamRepository.ServeEchoExtractedSubtitles(c) } func (h *Handler) HandleMediastreamGetAttachments(c echo.Context) error { return h.App.MediastreamRepository.ServeEchoExtractedAttachments(c) } // // Direct // func (h *Handler) HandleMediastreamDirectPlay(c echo.Context) error { client := "1" return h.App.MediastreamRepository.ServeEchoDirectPlay(c, client) } // // Transcode // func (h *Handler) HandleMediastreamTranscode(c echo.Context) error { client := "1" return h.App.MediastreamRepository.ServeEchoTranscodeStream(c, client) } // HandleMediastreamShutdownTranscodeStream // // @summary shuts down the transcode stream // @desc This requests the transcoder to shut down. It should be called when unmounting the player (playback is no longer needed). // @desc This will also send an events.MediastreamShutdownStream event. // @desc It will not return any error and is safe to call multiple times. // @returns bool // @route /api/v1/mediastream/shutdown-transcode [POST] func (h *Handler) HandleMediastreamShutdownTranscodeStream(c echo.Context) error { client := "1" h.App.MediastreamRepository.ShutdownTranscodeStream(client) return h.RespondWithData(c, true) } // // Serve file // func (h *Handler) HandleMediastreamFile(c echo.Context) error { client := "1" fp := c.QueryParam("path") libraryPaths := h.App.Settings.GetLibrary().GetLibraryPaths() return h.App.MediastreamRepository.ServeEchoFile(c, fp, client, libraryPaths) }