fix(Format): Parse xtags from protobuf to support SABR-only responses (#909)

This commit is contained in:
absidue
2025-02-27 07:30:43 +01:00
committed by GitHub
parent 06a0090ae6
commit 00c199ac69
3 changed files with 52 additions and 7 deletions

View File

@@ -35,6 +35,10 @@ export interface KeyValuePair {
value?: string | undefined;
}
export interface FormatXTags {
xtags: KeyValuePair[];
}
function createBaseHttpHeader(): HttpHeader {
return { name: undefined, value: undefined };
}
@@ -275,6 +279,42 @@ export const KeyValuePair: MessageFns<KeyValuePair> = {
},
};
function createBaseFormatXTags(): FormatXTags {
return { xtags: [] };
}
export const FormatXTags: MessageFns<FormatXTags> = {
encode(message: FormatXTags, writer: BinaryWriter = new BinaryWriter()): BinaryWriter {
for (const v of message.xtags) {
KeyValuePair.encode(v!, writer.uint32(10).fork()).join();
}
return writer;
},
decode(input: BinaryReader | Uint8Array, length?: number): FormatXTags {
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = createBaseFormatXTags();
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
if (tag !== 10) {
break;
}
message.xtags.push(KeyValuePair.decode(reader, reader.uint32()));
continue;
}
if ((tag & 7) === 4 || tag === 0) {
break;
}
reader.skip(tag & 7);
}
return message;
},
};
function longToNumber(int64: { toString(): string }): number {
const num = globalThis.Number(int64.toString());
if (num > globalThis.Number.MAX_SAFE_INTEGER) {

View File

@@ -25,4 +25,8 @@ message IndexRange {
message KeyValuePair {
optional string key = 1;
optional string value = 2;
}
message FormatXTags {
repeated KeyValuePair xtags = 1;
}

View File

@@ -1,5 +1,7 @@
import type Player from '../../../core/Player.js';
import type { RawNode } from '../../index.js';
import { FormatXTags } from '../../../../protos/generated/misc/common.js';
import { base64ToU8 } from '../../../utils/Utils.js';
export type ProjectionType = 'RECTANGULAR' | 'EQUIRECTANGULAR' | 'EQUIRECTANGULAR_THREED_TOP_BOTTOM' | 'MESH';
export type SpatialAudioType = 'AMBISONICS_5_1' | 'AMBISONICS_QUAD' | 'FOA_WITH_NON_DIEGETIC';
@@ -211,17 +213,16 @@ export default class Format {
};
if (this.has_audio || this.has_text) {
const args = new URLSearchParams(this.cipher || this.signature_cipher);
const url_components = new URLSearchParams(args.get('url') || this.url);
const xtags = this.xtags
? FormatXTags.decode(base64ToU8(decodeURIComponent(this.xtags).replace(/-/g, '+').replace(/_/g, '/'))).xtags
: [];
const xtags = url_components.get('xtags')?.split(':');
this.language = xtags?.find((x: string) => x.startsWith('lang='))?.split('=')[1] || null;
this.language = xtags.find((tag) => tag.key === 'lang')?.value || null;
if (this.has_audio) {
this.is_drc = !!data.isDrc || !!xtags?.includes('drc=1');
this.is_drc = !!data.isDrc || xtags.some((tag) => tag.key === 'drc' && tag.value === '1');
const audio_content = xtags?.find((x) => x.startsWith('acont='))?.split('=')[1];
const audio_content = xtags.find((tag) => tag.key === 'acont')?.value;
this.is_dubbed = audio_content === 'dubbed';
this.is_descriptive = audio_content === 'descriptive';
this.is_secondary = audio_content === 'secondary';