fix(mam-api): /stream returns MP4 url + separate hls_url (fixes Premiere import)
The HLS-VOD work made GET /assets/:id/stream return the HLS playlist URL as
`url` whenever hls_s3_key was set. The Premiere plugin's "Import Proxy"
downloads `url` to a file and imports it — so it was saving an .m3u8 playlist
as .mp4, and Premiere rejected it ("unsupported compression type"). This hit
every YouTube asset (all get HLS generated), regardless of codec.
/stream now returns the directly-downloadable MP4 proxy as `url` (type mp4)
and the HLS playlist as a separate `hls_url`. The web player prefers `hls_url`
(so in-browser HLS playback is unchanged), while the already-installed plugin
gets a real MP4 again — no plugin reinstall needed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
b449ef0ce3
commit
9d6bbf8112
2 changed files with 18 additions and 4 deletions
|
|
@ -595,10 +595,19 @@ router.get('/:id/stream', async (req, res, next) => {
|
||||||
if (r.rows.length === 0) return res.status(404).json({ error: 'Asset not found' });
|
if (r.rows.length === 0) return res.status(404).json({ error: 'Asset not found' });
|
||||||
const a = r.rows[0];
|
const a = r.rows[0];
|
||||||
if (a.status === 'live') return res.json({ url: `/live/${a.id}/index.m3u8`, type: 'hls', live: true });
|
if (a.status === 'live') return res.json({ url: `/live/${a.id}/index.m3u8`, type: 'hls', live: true });
|
||||||
// Prefer the HLS rendition for recorded assets — whole-file segment GETs
|
// `url` is the directly-downloadable MP4 proxy; `hls_url` is the HLS
|
||||||
// avoid the RustFS ranged-GET stitching the MP4 /video path has to do.
|
// rendition for in-browser playback (whole-file segment GETs avoid the
|
||||||
|
// RustFS ranged-GET stitching the MP4 path needs). The Premiere plugin
|
||||||
|
// downloads `url` to a file and imports it, so `url` must NOT be the
|
||||||
|
// .m3u8 playlist — Premiere can't import a playlist ("unsupported
|
||||||
|
// compression type"). The web player prefers `hls_url` when present.
|
||||||
if (a.hls_s3_key) {
|
if (a.hls_s3_key) {
|
||||||
return res.json({ url: `/api/v1/assets/${id}/hls/playlist.m3u8`, type: 'hls', source: 'proxy' });
|
return res.json({
|
||||||
|
url: `/api/v1/assets/${id}/video`,
|
||||||
|
type: 'mp4',
|
||||||
|
source: a.proxy_s3_key ? 'proxy' : 'original',
|
||||||
|
hls_url: `/api/v1/assets/${id}/hls/playlist.m3u8`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const VIDEO_EXTS = ['.mp4', '.mov', '.mxf', '.ts', '.m4v', '.mkv', '.avi', '.webm'];
|
const VIDEO_EXTS = ['.mp4', '.mov', '.mxf', '.ts', '.m4v', '.mkv', '.avi', '.webm'];
|
||||||
const key = a.proxy_s3_key ||
|
const key = a.proxy_s3_key ||
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,12 @@ function AssetDetail({ asset, onClose }) {
|
||||||
setStreamLoading(true);
|
setStreamLoading(true);
|
||||||
window.ZAMPP_API.fetch('/assets/' + assetId + '/stream')
|
window.ZAMPP_API.fetch('/assets/' + assetId + '/stream')
|
||||||
.then(function(r) {
|
.then(function(r) {
|
||||||
if (r && r.url) {
|
if (r && r.hls_url) {
|
||||||
|
// Prefer HLS for in-browser playback; `url` stays the MP4 proxy
|
||||||
|
// (used by the Premiere plugin importer + as a fallback).
|
||||||
|
setStreamUrl(r.hls_url);
|
||||||
|
setStreamType('hls');
|
||||||
|
} else if (r && r.url) {
|
||||||
setStreamUrl(r.url);
|
setStreamUrl(r.url);
|
||||||
setStreamType(r.type || 'mp4');
|
setStreamType(r.type || 'mp4');
|
||||||
} else if (r) {
|
} else if (r) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue