web/libav: fix video/audio detection when using polyfill

This commit is contained in:
dumbmoron 2024-08-23 18:40:24 +00:00
parent 9410f613e4
commit 43b3db1317
No known key found for this signature in database
2 changed files with 66 additions and 7 deletions

View file

@ -134,10 +134,16 @@ export default class EncodeLibAV extends LibAVWrapper {
}
// FIXME: figure out how to make typescript happy without this monstrosity
if (value instanceof AudioData && encoder instanceof AudioEncoder) {
encoder.encode(value);
} else if (value instanceof VideoFrame && encoder instanceof VideoEncoder) {
encoder.encode(value);
if (WebCodecsWrapper.isVideo(encoder)) {
WebCodecsWrapper.sendVideo(
value as VideoFrame,
encoder as VideoEncoder
);
} else {
WebCodecsWrapper.sendAudio(
value as AudioData,
encoder as AudioEncoder
);
}
value.close();
@ -165,7 +171,7 @@ export default class EncodeLibAV extends LibAVWrapper {
const { libav } = await this.#get();
let convertToPacket;
if (chunk instanceof EncodedVideoChunk) {
if (WebCodecsWrapper.isVideo(chunk)) {
convertToPacket = LibAVWebCodecs.encodedVideoChunkToPacket;
} else {
convertToPacket = LibAVWebCodecs.encodedAudioChunkToPacket;
@ -261,9 +267,9 @@ export default class EncodeLibAV extends LibAVWrapper {
#decodePacket(decoder: Decoder, packet: Packet, stream: Stream) {
let chunk;
if (decoder instanceof VideoDecoder) {
if (WebCodecsWrapper.isVideo(decoder)) {
chunk = LibAVWebCodecs.packetToEncodedVideoChunk(packet, stream);
} else if (decoder instanceof AudioDecoder) {
} else if (WebCodecsWrapper.isAudio(decoder)) {
chunk = LibAVWebCodecs.packetToEncodedAudioChunk(packet, stream);
}

View file

@ -110,4 +110,57 @@ export default class WebCodecsWrapper {
return decoder;
}
static isVideo(obj: unknown) {
return ('VideoEncoder' in window && obj instanceof VideoEncoder)
|| ('VideoDecoder' in window && obj instanceof VideoDecoder)
|| ('VideoFrame' in window && obj instanceof VideoFrame)
|| ('EncodedVideoChunk' in window && obj instanceof EncodedVideoChunk)
|| obj instanceof LibAVPolyfill.VideoEncoder
|| obj instanceof LibAVPolyfill.VideoDecoder
|| obj instanceof LibAVPolyfill.VideoFrame
|| obj instanceof LibAVPolyfill.EncodedVideoChunk;
}
static isAudio(obj: unknown) {
return ('AudioEncoder' in window && obj instanceof AudioEncoder)
|| ('AudioDecoder' in window && obj instanceof AudioDecoder)
|| ('AudioData' in window && obj instanceof AudioData)
|| ('EncodedAudioChunk' in window && obj instanceof EncodedAudioChunk)
|| obj instanceof LibAVPolyfill.AudioEncoder
|| obj instanceof LibAVPolyfill.AudioDecoder
|| obj instanceof LibAVPolyfill.AudioData
|| obj instanceof LibAVPolyfill.EncodedAudioChunk;
}
static sendAudio(data: AudioData | LibAVPolyfill.AudioData, destination: AudioEncoder) {
if (destination instanceof LibAVPolyfill.AudioEncoder) {
if ('AudioData' in window && data instanceof AudioData) {
const converted = LibAVPolyfill.AudioData.fromNative(data);
data.close();
data = converted;
}
} else {
if (data instanceof LibAVPolyfill.AudioData) {
data = data.toNative({ transfer: true });
}
}
return destination.encode(data);
}
static sendVideo(data: VideoFrame | LibAVPolyfill.VideoFrame, destination: VideoEncoder) {
if (destination instanceof LibAVPolyfill.VideoEncoder) {
if ('VideoFrame' in window && data instanceof VideoFrame) {
const converted = LibAVPolyfill.VideoFrame.fromNative(data);
data.close();
data = converted;
}
} else {
if (data instanceof LibAVPolyfill.VideoFrame) {
data = data.toNative({ transfer: true });
}
}
return destination.encode(data as VideoFrame);
}
}