mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-15 04:43:41 +00:00
fix(hls): enforce supported HLS subset with explicit errors
The merge pipeline concatenates stored bytes, so features it cannot reproduce faithfully are now detected and rejected with a clear error instead of silently succeeding with a broken output: - EXT-X-GAP (a hole in the merged file) and EXT-X-DISCONTINUITY (a broken timeline) - separate audio renditions referenced by the selected variant: the master EXT-X-MEDIA groups are parsed and an AUDIO group with its own URI fails the resolve; unreferenced groups are ignored - changing init sections: a repeated EXT-X-MAP is compared by all of its attributes (URI and BYTERANGE), not just the URI - encrypted EXT-X-MAP without an explicit IV: the spec does not define a sequence-derived IV for init sections - non-identity AES-128 KEYFORMAT values The supported matrix is documented in the package doc. Add regression tests for every rejection plus real media validation: ffmpeg-generated TS segments and fMP4 init/fragments are committed as fixtures, downloaded through the fetcher (including an AES-128 key rotation variant), and the merged outputs are validated structurally - TS on the 188 byte grid with continuity counter rules, PAT/PMT and PES presence, fMP4 by walking the ISO-BMFF box hierarchy.
This commit is contained in:
1 parent
675028c64a
commit
f1f17948c6
12 files changed
+611
-32
No files matched your search
@@ -227,11 +227,14 @@ func (f *Fetcher) resolvePlanLocked(ctx context.Context, keepName string) (*fetc
|
||||
|
||||
mediaURL := finalURL
|
||||
if IsMasterPlaylist(content) {
|
||||
variants, err := ParseMaster(content, baseURL)
|
||||
master, err := ParseMasterPlaylist(content, baseURL)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
best := PickBestVariant(variants)
|
||||
best := PickBestVariant(master.Variants)
|
||||
if err := checkAudioRendition(master, best); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
variantContent, variantURL, err := f.fetchText(ctx, http.MethodGet, best.URI)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("fetch variant playlist failed: %w", err)
|
||||
@@ -248,8 +251,8 @@ func (f *Fetcher) resolvePlanLocked(ctx context.Context, keepName string) (*fetc
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
if media.Live {
|
||||
return nil, "", errors.New("live streams are not supported yet")
|
||||
if err := validateSupported(media); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
outputName := keepName
|
||||
|
||||
Reference in new issue
Block a user