You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:45:01