@geekapps/silo-elements-nextjs 0.3.18 → 0.3.20

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.
@@ -29,24 +29,98 @@ function deviceSupportsOpus() {
29
29
  return false;
30
30
  }
31
31
  }
32
- function deviceSupportsCodec(codecStr) {
33
- if (typeof window === "undefined") return true;
32
+ function deviceSupportsVideoCodec(codec) {
33
+ if (!codec || typeof window === "undefined") return true;
34
+ if (/^avc1/i.test(codec)) return true;
34
35
  try {
35
36
  if (typeof MediaSource !== "undefined" && MediaSource.isTypeSupported) {
36
- return MediaSource.isTypeSupported(`video/mp4; codecs="${codecStr}"`);
37
+ return MediaSource.isTypeSupported(`video/mp4; codecs="${codec}"`);
37
38
  }
38
39
  return true;
39
40
  } catch {
40
41
  return true;
41
42
  }
42
43
  }
44
+ function deviceSupportsAudioCodec(codec) {
45
+ if (!codec || typeof window === "undefined") return true;
46
+ if (/^mp4a/i.test(codec)) return true;
47
+ if (/^opus/i.test(codec)) return deviceSupportsOpus();
48
+ try {
49
+ if (typeof MediaSource !== "undefined" && MediaSource.isTypeSupported) {
50
+ return MediaSource.isTypeSupported(`audio/mp4; codecs="${codec}"`);
51
+ }
52
+ const a = document.createElement("audio");
53
+ return a.canPlayType(`audio/mp4; codecs="${codec}"`) !== "";
54
+ } catch {
55
+ return true;
56
+ }
57
+ }
58
+ var LANG_NAMES = {
59
+ pt: "Portugu\xEAs",
60
+ "pt-br": "Portugu\xEAs (Brasil)",
61
+ "pt-pt": "Portugu\xEAs (Portugal)",
62
+ en: "English",
63
+ "en-us": "English (US)",
64
+ "en-gb": "English (UK)",
65
+ es: "Espa\xF1ol",
66
+ "es-419": "Espa\xF1ol (Latino)",
67
+ fr: "Fran\xE7ais",
68
+ de: "Deutsch",
69
+ it: "Italiano",
70
+ ja: "\u65E5\u672C\u8A9E",
71
+ ko: "\uD55C\uAD6D\uC5B4",
72
+ zh: "\u4E2D\u6587",
73
+ "zh-cn": "\u666E\u901A\u8BDD",
74
+ "zh-tw": "\u7E41\u9AD4\u4E2D\u6587",
75
+ ru: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439",
76
+ ar: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629",
77
+ hi: "\u0939\u093F\u0928\u094D\u0926\u0940",
78
+ nl: "Nederlands",
79
+ pl: "Polski",
80
+ sv: "Svenska",
81
+ tr: "T\xFCrk\xE7e",
82
+ und: "Original"
83
+ };
84
+ var CODEC_LABELS = {
85
+ "truehd": "Dolby TrueHD",
86
+ "atmos": "Dolby Atmos",
87
+ "eac3": "Dolby Digital Plus",
88
+ "ec-3": "Dolby Digital Plus",
89
+ "e-ac-3": "Dolby Digital Plus",
90
+ "ac3": "Dolby Digital",
91
+ "ac-3": "Dolby Digital",
92
+ "dts-hd": "DTS-HD",
93
+ "dts-hd ma": "DTS-HD MA",
94
+ "dtshd": "DTS-HD MA",
95
+ "dts": "DTS",
96
+ "aac": "AAC",
97
+ "opus": "Opus",
98
+ "mp3": "MP3",
99
+ "flac": "FLAC",
100
+ "alac": "ALAC"
101
+ };
102
+ var CHANNEL_LABELS = {
103
+ 1: "Mono",
104
+ 2: "Est\xE9reo",
105
+ 6: "5.1",
106
+ 7: "6.1",
107
+ 8: "7.1"
108
+ };
109
+ function friendlyAudioLabel(rawName, lang, codec, channels) {
110
+ const langKey = (lang ?? "").toLowerCase();
111
+ const langLabel = LANG_NAMES[langKey] ?? (lang ? lang.toUpperCase() : null);
112
+ const codecKey = Object.keys(CODEC_LABELS).find((k) => codec.toLowerCase().includes(k));
113
+ const codecLabel = codecKey ? CODEC_LABELS[codecKey] : null;
114
+ const chLabel = channels ? CHANNEL_LABELS[channels] ?? `${channels}ch` : null;
115
+ const looksHuman = rawName && !/^(und|dts|ac3|eac3|aac|opus|truehd|atmos|\w{2,3}-\d+ch|\w{2})/i.test(rawName) && rawName.length > 1;
116
+ const baseName = looksHuman ? rawName : langLabel ?? "\xC1udio";
117
+ const suffix = [codecLabel, chLabel].filter(Boolean).join(" ");
118
+ return suffix ? `${baseName} \u2014 ${suffix}` : baseName;
119
+ }
43
120
  function isHdrLevel(level) {
44
121
  const range = level?.videoRange ?? level?.video_range ?? "";
45
122
  return range === "PQ" || range === "HLG" || range === "HDR10" || typeof level?.name === "string" && /hdr/i.test(level.name);
46
123
  }
47
- function isHdrAudioCodec(codecStr) {
48
- return /opus/i.test(codecStr);
49
- }
50
124
  var PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2];
51
125
  function Source(_props) {
52
126
  return null;
@@ -832,10 +906,14 @@ function Video({
832
906
  AUTO_QUALITY,
833
907
  ...levels.map((level, index) => {
834
908
  const hdr = isHdrLevel(level);
835
- const codecStr = level.videoCodec ?? level.attrs?.CODECS ?? "";
836
- const supported = hdr ? hdrSupported : deviceSupportsCodec(codecStr);
909
+ const rawCodecs = (level.attrs?.CODECS ?? "").split(",").map((c) => c.trim());
910
+ const videoCodec = level.videoCodec ?? rawCodecs.find((c) => /^avc1|^hvc1|^hev1|^av01|^vp09/i.test(c)) ?? rawCodecs[0] ?? "";
911
+ const audioCodec = level.audioCodec ?? rawCodecs.find((c) => /^mp4a|^opus|^ec-3|^ac-3/i.test(c)) ?? "";
912
+ const videoOk = deviceSupportsVideoCodec(videoCodec);
913
+ const audioOk = deviceSupportsAudioCodec(audioCodec);
914
+ const supported = (hdr ? hdrSupported : true) && videoOk && audioOk;
837
915
  const baseName = level.name ?? (level.height ? `${level.height}p` : `${index + 1}`);
838
- const label = hdr ? `${baseName} HDR` : baseName;
916
+ const label = hdr && hdrSupported ? `${baseName} HDR` : baseName;
839
917
  return { id: `hls-${index}`, label, type: "hls", index, supported, hdr };
840
918
  })
841
919
  ]);
@@ -844,9 +922,10 @@ function Video({
844
922
  if (tracks.length > 1) {
845
923
  setAudioTracks(
846
924
  tracks.map((t, i) => {
847
- const codec = t.attrs?.CODECS ?? t.codecSet ?? "";
848
- const supported = isHdrAudioCodec(codec) ? opusSupported : true;
849
- return { id: i, label: t.name ?? t.lang ?? `Track ${i + 1}`, supported };
925
+ const codec = (t.attrs?.CODECS ?? t.codecSet ?? "").split(",")[0]?.trim() ?? "";
926
+ const supported = deviceSupportsAudioCodec(codec);
927
+ const label = friendlyAudioLabel(t.name, t.lang, codec, t.channels ?? t.attrs?.CHANNELS);
928
+ return { id: i, label, supported };
850
929
  })
851
930
  );
852
931
  if (pinnedAudio === -1) setSelectedAudio(hls.audioTrack ?? 0);
@@ -858,13 +937,13 @@ function Video({
858
937
  hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, (_, data) => {
859
938
  const tracks = data.audioTracks ?? [];
860
939
  console.debug("[Silo/hls] AUDIO_TRACKS_UPDATED", tracks.length);
861
- const opusSupported = deviceSupportsOpus();
862
940
  if (tracks.length > 1) {
863
941
  setAudioTracks(
864
942
  tracks.map((t, i) => {
865
- const codec = t.attrs?.CODECS ?? t.codecSet ?? "";
866
- const supported = isHdrAudioCodec(codec) ? opusSupported : true;
867
- return { id: i, label: t.name ?? t.lang ?? `Track ${i + 1}`, supported };
943
+ const codec = (t.attrs?.CODECS ?? t.codecSet ?? "").split(",")[0]?.trim() ?? "";
944
+ const supported = deviceSupportsAudioCodec(codec);
945
+ const label = friendlyAudioLabel(t.name, t.lang, codec, t.channels ?? t.attrs?.CHANNELS);
946
+ return { id: i, label, supported };
868
947
  })
869
948
  );
870
949
  }