@geekapps/silo-elements-nextjs 0.3.21 → 0.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,9 +20,8 @@ function deviceSupportsHdr() {
20
20
  function deviceSupportsOpus() {
21
21
  if (typeof window === "undefined") return false;
22
22
  try {
23
- if (typeof MediaSource !== "undefined" && MediaSource.isTypeSupported) {
24
- if (MediaSource.isTypeSupported('audio/mp4; codecs="opus"')) return true;
25
- }
23
+ if (typeof MediaSource !== "undefined" && MediaSource.isTypeSupported)
24
+ return MediaSource.isTypeSupported('audio/mp4; codecs="opus"');
26
25
  const a = document.createElement("audio");
27
26
  return a.canPlayType('audio/ogg; codecs="opus"') !== "" || a.canPlayType('video/mp4; codecs="opus"') !== "";
28
27
  } catch {
@@ -873,6 +872,12 @@ function Video({
873
872
  const Hls = HlsModule.default;
874
873
  console.debug("[Silo/hls] Hls.isSupported()=", Hls.isSupported());
875
874
  if (Hls.isSupported()) {
875
+ let audioCodecPriority2 = function(codec) {
876
+ const c = codec.toLowerCase();
877
+ const idx = AUDIO_CODEC_PRIORITY.findIndex((k) => c.includes(k));
878
+ return idx === -1 ? 0 : idx;
879
+ };
880
+ var audioCodecPriority = audioCodecPriority2;
876
881
  const hls = new Hls({
877
882
  enableWorker: true,
878
883
  // Buffer ~20s ahead (≈1/6 of a 2min video). maxMaxBufferLength caps the
@@ -934,32 +939,36 @@ function Video({
934
939
  if (pinnedAudio >= 0) hls.audioTrack = pinnedAudio;
935
940
  setIsLoading(false);
936
941
  });
942
+ const AUDIO_CODEC_PRIORITY = ["opus", "mp4a", "aac", "ac-3", "ac3", "dts", "ec-3", "eac3", "dts-hd", "dtshd", "truehd"];
943
+ let audioUpgradeDone = false;
944
+ let mappedAudioTracks = [];
937
945
  hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, (_, data) => {
938
946
  const tracks = data.audioTracks ?? [];
939
947
  console.debug("[Silo/hls] AUDIO_TRACKS_UPDATED", tracks.length);
940
948
  if (tracks.length > 0) {
941
- const mapped = tracks.map((t, i) => {
949
+ mappedAudioTracks = tracks.map((t, i) => {
942
950
  const codec = (t.attrs?.CODECS ?? t.codecSet ?? "").split(",")[0]?.trim() ?? "";
943
951
  const supported = deviceSupportsAudioCodec(codec);
944
952
  const label = friendlyAudioLabel(t.name, t.lang, codec, t.channels ?? t.attrs?.CHANNELS);
945
- return { id: i, label, supported };
953
+ return { id: i, label, supported, codec };
946
954
  });
947
- const currentTrackIdx = hls.audioTrack ?? 0;
948
- if (mapped[currentTrackIdx] && !mapped[currentTrackIdx].supported) {
949
- const firstSupported = mapped.findIndex((t) => t.supported);
950
- if (firstSupported >= 0) {
951
- console.debug("[Silo/hls] current audio track unsupported \u2014 switching to track", firstSupported);
952
- hls.audioTrack = firstSupported;
953
- if (pinnedAudio === -1) setSelectedAudio(firstSupported);
955
+ if (pinnedAudio === -1) {
956
+ const opusTrack = mappedAudioTracks.find((t) => t.supported && /opus/i.test(t.codec));
957
+ const fallback = mappedAudioTracks.find((t) => t.supported);
958
+ const startTrack = opusTrack ?? fallback;
959
+ if (startTrack) {
960
+ hls.audioTrack = startTrack.id;
961
+ setSelectedAudio(startTrack.id);
962
+ console.debug("[Silo/hls] starting with audio track", startTrack.id, startTrack.codec);
954
963
  } else {
955
- console.warn("[Silo/hls] no supported audio track found \u2014 disabling separate audio");
964
+ console.warn("[Silo/hls] no supported audio track found \u2014 disabling");
956
965
  try {
957
966
  hls.audioTrack = -1;
958
967
  } catch {
959
968
  }
960
969
  }
961
970
  }
962
- if (mapped.length > 1) setAudioTracks(mapped);
971
+ if (mappedAudioTracks.length > 1) setAudioTracks(mappedAudioTracks.map(({ id, label, supported }) => ({ id, label, supported })));
963
972
  }
964
973
  if (pinnedAudio >= 0 && hls.audioTrack !== pinnedAudio) {
965
974
  hls.audioTrack = pinnedAudio;
@@ -991,6 +1000,16 @@ function Video({
991
1000
  });
992
1001
  hls.on(Hls.Events.FRAG_LOADED, (_, data) => {
993
1002
  console.debug("[Silo/hls] FRAG_LOADED", data.frag?.type, data.frag?.sn);
1003
+ if (!audioUpgradeDone && data.frag?.type === "audio" && data.frag?.sn === 0 && pinnedAudio === -1 && mappedAudioTracks.length > 1) {
1004
+ audioUpgradeDone = true;
1005
+ const supported = mappedAudioTracks.filter((t) => t.supported);
1006
+ const best = supported.reduce((a, b) => audioCodecPriority2(b.codec) > audioCodecPriority2(a.codec) ? b : a, supported[0]);
1007
+ if (best && best.id !== hls.audioTrack) {
1008
+ console.debug("[Silo/hls] upgrading audio track", hls.audioTrack, "\u2192", best.id, best.codec);
1009
+ hls.audioTrack = best.id;
1010
+ setSelectedAudio(best.id);
1011
+ }
1012
+ }
994
1013
  });
995
1014
  let mediaErrorAttempts = 0;
996
1015
  let audioAppendErrors = 0;
@@ -1003,8 +1022,8 @@ function Video({
1003
1022
  const isAudioBufError = fragType === "audio" && (data.details === Hls.ErrorDetails.BUFFER_APPEND_ERROR || data.details === Hls.ErrorDetails.BUFFER_APPENDING_ERROR);
1004
1023
  if (isAudioBufError) {
1005
1024
  audioAppendErrors += 1;
1006
- if (audioAppendErrors >= 3) {
1007
- console.warn("[Silo/hls] repeated audio buffer errors \u2014 disabling separate audio tracks");
1025
+ if (audioAppendErrors >= 1) {
1026
+ console.warn("[Silo/hls] audio buffer append error \u2014 disabling separate audio tracks");
1008
1027
  setAudioTracks([]);
1009
1028
  try {
1010
1029
  hls.audioTrack = -1;