JS前端如何解析分段MP4视频中的esds配置信息
从HTTP分段MP4中提取moov->trak->mdia->esds配置数据
我有一台支持HTTP视频流的服务器,可通过带Range头的HTTP GET请求发送视频分段数据。将链接直接放入video标签可在Chrome中正常播放,但我需要在页面播放前从这些MP4分块中提取特定配置的原始数据(具体路径为moov -> trak -> mdia -> esds),请问该如何查找这些配置?以下是我已有的代码:
1. 小端字节序转大端字节序的数字解析函数
function parseNumber(data: Uint8Array, offset: number, size: number) { let result: number = 0 for(let i = offset; i < size; i++) { result += data[i] * 256 ^ (i - offset) } return result }
2. 字符串解析函数
function parseString(data: Uint8Array, offset: number, size: number) { return String.fromCharCode(...data.slice(offset, offset + size)); }
3. 在Atom内容中查找子Atom的函数
function lookForChildAtom(data: Uint8Array, offset: number, size: number, lookFor: string | string[]) { while(offset < size) { let [childAtomSize, childAtomName] = parseAtomSizeAndName(data, offset) if(childAtomSize === 1 && childAtomName === 'mdat') { childAtomSize = parseNumber(data, offset + 8, 16) } if(childAtomSize < (MIN_SIZES[childAtomName] ?? 8)) { throw Error('The file is invalid: ' + childAtomName + ' atom < ' + MIN_SIZES[childAtomName] ?? '8') } if(lookFor instanceof Array && lookFor.includes(childAtomName) || childAtomName === lookFor) { return [offset, childAtomSize] } offset += childAtomSize } return [offset, 0] }
4. 提取ESDS数据的主函数
export default function parseMp4ForESDSData(data: Uint8Array) : string { let offset = 0; let size: number = data.length; [offset, size] = lookForChildAtom(data, offset, size, ['moov', 'moof']); while(true) { const [trakOffset, trakSize] = lookForChildAtom(data, offset, size, 'trak'); const [mdiaOffset, mdiaSize] = lookForChildAtom(data, trakOffset, trakSize, 'mdia'); const [hdlrOffset, hdlrSize] = lookForChildAtom(data, mdiaOffset, mdiaSize, 'hdlr'); const hdlrSubtype = parseString(data, hdlrOffset + HDLRSubtypeStart, HDLRSubtypeSize) if(hdlrSubtype === 'soun') { [offset, size] = [mdiaOffset, mdiaSize] break } const trackEnd = trakOffset + trakSize offset += trackEnd size -= trackEnd if(size <= 0) { throw Error('No sound track in the file') } } [offset, size] = lookForChildAtom(data, offset, size, 'minf'); [offset, size] = lookForChildAtom(data, offset, size, 'mp4a'); [offset, size] = lookForChildAtom(data, offset, size, 'esds'); offset += ESDSElementaryStreamDescriptorStart size -= ESDSElementaryStreamDescriptorStart return parseString(data, offset, offset + size) }
内容的提问来源于stack exchange,提问作者Alexey_Chebotarev
相关产品推荐
相关产品推荐

