Release v0.2.34
This commit is contained in:
@@ -373,6 +373,21 @@ func (c *Client) SetPlayed(ctx context.Context, cred Credentials, itemID string,
|
||||
return c.userDataCall(ctx, method, path, cred)
|
||||
}
|
||||
|
||||
// HideFromResume removes an item from resume and next-up feeds without marking it played.
|
||||
func (c *Client) HideFromResume(ctx context.Context, cred Credentials, itemID string) (json.RawMessage, error) {
|
||||
params := url.Values{"Hide": {"true"}}
|
||||
path := "/Users/" + url.PathEscape(cred.UserID) + "/Items/" + url.PathEscape(itemID) + "/HideFromResume"
|
||||
req, err := c.newRequest(ctx, http.MethodPost, path, params, cred, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var raw json.RawMessage
|
||||
if err := c.do(req, &raw); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return raw, nil
|
||||
}
|
||||
|
||||
// RefreshItem asks Emby to re-scan one item's files.
|
||||
//
|
||||
// It exists for the subtitle download: Bazarr writes the new .srt beside the media file
|
||||
@@ -501,6 +516,43 @@ func (c *Client) TrickplayBytes(
|
||||
return io.ReadAll(io.LimitReader(resp.Body, to-from+1))
|
||||
}
|
||||
|
||||
// MaxSubtitleBytes caps a subtitle read. A feature-length SubRip file is tens of
|
||||
// kilobytes; a megabyte is far past anything genuine and is what an Emby that answered
|
||||
// with the media file instead would send.
|
||||
const MaxSubtitleBytes = 4 << 20
|
||||
|
||||
// SubtitleBytes reads a text subtitle track's content.
|
||||
//
|
||||
// This is the one place the gateway pulls a subtitle *out* of Emby rather than pointing
|
||||
// the television at it, and it exists so a track can be used as a timing reference. SubRip
|
||||
// is asked for because that is what the sync reads and writes; Emby converts from whatever
|
||||
// the container holds.
|
||||
func (c *Client) SubtitleBytes(
|
||||
ctx context.Context, cred Credentials, itemID, mediaSourceID string, index int,
|
||||
) ([]byte, error) {
|
||||
if mediaSourceID == "" {
|
||||
mediaSourceID = itemID
|
||||
}
|
||||
path := fmt.Sprintf(
|
||||
"/Videos/%s/%s/Subtitles/%d/Stream.srt",
|
||||
url.PathEscape(itemID), url.PathEscape(mediaSourceID), index,
|
||||
)
|
||||
req, err := c.newRequest(ctx, http.MethodGet, path, nil, cred, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := c.http.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode >= 400 {
|
||||
body, _ := io.ReadAll(io.LimitReader(resp.Body, 2048))
|
||||
return nil, &APIError{StatusCode: resp.StatusCode, Body: string(body)}
|
||||
}
|
||||
return io.ReadAll(io.LimitReader(resp.Body, MaxSubtitleBytes))
|
||||
}
|
||||
|
||||
// StreamURL is the direct-play URL handed to the TV. It points at the *public* Emby
|
||||
// address: video never flows through the gateway, only metadata does.
|
||||
func (c *Client) StreamURL(cred Credentials, itemID string) string {
|
||||
|
||||
Reference in New Issue
Block a user