files: video previews are made on the Transcode device too

The setting's device makes every video preview: on the file's own machine
when it is there (the hub tells it by header), else on the device's machine,
which reads the file through the hub by a one-file token, and the preview is
kept in the file's machine's own cache (PUT /api/files/thumb, refused if the
file changed). Images and covers stay on the file's machine's CPU. If the
device's machine can't, the file's makes it as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Mitchell-Johnson
2026-10-23 16:07:00 -07:00
co-authored by Claude Opus 5.5
parent 1464e1f7a0
commit d5c16540a1
7 changed files with 335 additions and 12 deletions
+10 -4
View File
@@ -383,13 +383,19 @@ func (m *Manager) PushAll(ctx context.Context, binPath, ourArch string, force bo
// WebSocket origin check (meant for browsers) doesn't reject the hub.
// Do makes one request to a managed machine as this hub and returns the whole response.
func (m *Manager) Do(ctx context.Context, name, method, path string, body []byte, hdr http.Header) (int, []byte, error) {
code, b, _, err := m.DoHeaders(ctx, name, method, path, body, hdr)
return code, b, err
}
// DoHeaders is Do that also answers the response's headers.
func (m *Manager) DoHeaders(ctx context.Context, name, method, path string, body []byte, hdr http.Header) (int, []byte, http.Header, error) {
n, ok := m.node(name)
if !ok {
return 0, nil, errors.New("no such machine")
return 0, nil, nil, errors.New("no such machine")
}
req, err := http.NewRequestWithContext(ctx, method, strings.TrimRight(n.URL, "/")+path, bytes.NewReader(body))
if err != nil {
return 0, nil, err
return 0, nil, nil, err
}
for k, v := range hdr {
req.Header[k] = v
@@ -397,11 +403,11 @@ func (m *Manager) Do(ctx context.Context, name, method, path string, body []byte
req.Header.Set("Authorization", "Bearer "+n.Token)
resp, err := m.client(n).Do(req)
if err != nil {
return 0, nil, errors.New(shortErr(err))
return 0, nil, nil, errors.New(shortErr(err))
}
defer resp.Body.Close()
b, err := io.ReadAll(io.LimitReader(resp.Body, 8<<20))
return resp.StatusCode, b, err
return resp.StatusCode, b, resp.Header, err
}
// URL is a managed machine's address, "" for one not managed here.