Skip to content

Commit 3fa5df1

Browse files
authored
HLS manifests that don't end in .m3u8 if the format is right. (#198)
* Add a test for HLS loading with a parameter. * Support a variety of HLS formats. Closes #197
1 parent fa10a7a commit 3fa5df1

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

src/components/Viewer/Player/Player.test.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Vault } from "@iiif/vault";
99
import { ViewerProvider } from "src/context/viewer-context";
1010
import manifestSimpleAudio from "src/fixtures/viewer/player/manifest-simple-audio.json";
1111
import manifestStreaming from "src/fixtures/viewer/player/manifest-streaming-audio.json";
12+
import Hls from "hls.js";
1213

1314
describe("Player component", () => {
1415
let originalLoad: any;
@@ -82,6 +83,69 @@ describe("Player component", () => {
8283
expect(screen.getByRole("presentation")).toBeInTheDocument();
8384
});
8485

86+
it("renders the Player component for a streaming audio file even if a parameter is at the end, loading hls", async () => {
87+
const allSources = [
88+
{
89+
id: "https://meadow-streaming.rdc-staging.library.northwestern.edu/03/4a/07/03/-b/4d/3-/48/62/-b/fd/f-/85/f5/ba/8e/d1/40/034a0703-b4d3-4862-bfdf-85f5ba8ed140.m3u8?test=1",
90+
type: "Sound",
91+
format: "application/x-mpegurl",
92+
height: 100,
93+
width: 100,
94+
duration: 268.776,
95+
},
96+
];
97+
98+
const painting = {
99+
id: "https://meadow-streaming.rdc-staging.library.northwestern.edu/03/4a/07/03/-b/4d/3-/48/62/-b/fd/f-/85/f5/ba/8e/d1/40/034a0703-b4d3-4862-bfdf-85f5ba8ed140.m3u8?test=1",
100+
type: "Sound",
101+
format: "application/x-mpegurl",
102+
height: 100,
103+
width: 100,
104+
duration: 268.776,
105+
};
106+
107+
const annotationResources = [];
108+
109+
const props = {
110+
allSources: allSources as LabeledIIIFExternalWebResource[],
111+
painting: painting as LabeledIIIFExternalWebResource,
112+
annotationResources: annotationResources as AnnotationResources,
113+
};
114+
115+
const hlsSpy = vi.spyOn(Hls.prototype, "attachMedia");
116+
117+
const vault = new Vault();
118+
await vault.loadManifest("", manifestStreaming);
119+
120+
render(
121+
<ViewerProvider
122+
initialState={{
123+
activeCanvas:
124+
"https://dcapi.rdc-staging.library.northwestern.edu/api/v2/works/d2a423b1-6b5e-45cb-9956-46a99cd62cfd?as=iiif/canvas/access/0",
125+
activeManifest:
126+
"https://dcapi.rdc-staging.library.northwestern.edu/api/v2/works/d2a423b1-6b5e-45cb-9956-46a99cd62cfd?as=iiif",
127+
collection: {},
128+
configOptions: {},
129+
customDisplays: [],
130+
isInformationOpen: false,
131+
isLoaded: false,
132+
vault,
133+
openSeadragonViewer: null,
134+
}}
135+
>
136+
<Player {...props} />
137+
</ViewerProvider>,
138+
);
139+
140+
expect(screen.getByTestId("player-wrapper")).toBeInTheDocument();
141+
142+
// Test for the audio visualizer
143+
expect(screen.getByRole("presentation")).toBeInTheDocument();
144+
145+
// Test for Hls Attach
146+
expect(hlsSpy).toHaveBeenCalled();
147+
});
148+
85149
it("renders the Player component for a standard audio file", async () => {
86150
const allSources = [
87151
{

src/components/Viewer/Player/Player.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { LabeledIIIFExternalWebResource } from "src/types/presentation-3";
99
import { PlayerWrapper } from "src/components/Viewer/Player/Player.styled";
1010
import Track from "src/components/Viewer/Player/Track";
1111
import { getPaintingResource } from "src/hooks/use-iiif";
12+
import { hlsMimeTypes } from "src/lib/hls";
1213

1314
// Set referrer header as a NU domain: ie. meadow.rdc-staging.library.northwestern.edu
1415

@@ -51,8 +52,14 @@ const Player: React.FC<PlayerProps> = ({
5152
/**
5253
* Eject HLS attachment if file extension from
5354
* the IIIF content resource ID is not .m3u8
55+
* and format is not one of many m3u8 formats.
5456
*/
55-
if (painting.id.split(".").pop() !== "m3u8") return;
57+
if (
58+
painting.id.split(".").pop() !== "m3u8" &&
59+
painting.format &&
60+
!hlsMimeTypes.includes(painting.format)
61+
)
62+
return;
5663

5764
// Construct HLS.js config
5865
const config = {

src/lib/hls.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export const hlsMimeTypes = [
2+
// Apple santioned
3+
"application/vnd.apple.mpegurl",
4+
"vnd.apple.mpegurl",
5+
// Apple sanctioned for backwards compatibility
6+
"audio/mpegurl",
7+
// Very common
8+
"audio/x-mpegurl",
9+
// Very common
10+
"application/x-mpegurl",
11+
// Included for completeness
12+
"video/x-mpegurl",
13+
"video/mpegurl",
14+
"application/mpegurl",
15+
];

0 commit comments

Comments
 (0)