如何从中间获取mp4视频文件的片段,但使用nodejs aws保留文件元数据

问题描述 投票:0回答:1
export async function* initiateObjectStream(
  Key: string,
  start: number,
  end: number,
): AsyncGenerator<any, any, unknown> {
  const streamRange = `bytes=${start}-${end}`;

  const getObjectCommand = new GetObjectCommand({
    Bucket: bucket,
    Key,
    Range: streamRange,
  });

  const { Body: chunks} = await s3Client.send(getObjectCommand);


  for await (const chunk of chunks) {
    yield chunk;
  }

}

我使用此函数获取 mp4 视频文件,稍后将其传输到 HTML 视频播放器

当 start = 0 参数传递给函数参数时,一切正常。因为视频文件的块是从头开始播放的。视频的前几个块具有必要的元数据,向 HTML 视频播放器指示这是一个视频并且应该显示它

当我想不是从头开始而是从中间显示视频时,起始值是不同的。 B 来自 AWS,我收到一个视频片段,其中不再包含带有元数据的第一个块。因此,HTML 视频播放器在收到需要元数据的前 3 个块后会关闭流

如何通过 aws 获取包含文件元数据的第一个块并将它们与所需片段的块粘合?

或者我如何自己创建第一个元数据块?我应该在元数据中指定哪些值?


我试图通过其他块添加元数据,但这对我没有帮助

export async function* initiateObjectStream(
  Key: string,
  start: number,
  end: number,
): AsyncGenerator<any, any, unknown> {
  const streamRange = `bytes=${start}-${end}`;

  const getObjectCommand = new GetObjectCommand({
    Bucket: bucket,
    Key,
    Range: streamRange,
  });

  const { Body: chunks } = await s3Client.send(getObjectCommand);

  //@ts-ignore
  const passThroughStream = new PassThrough();

  const ftypChunk = Buffer.alloc(28);
  ftypChunk.writeUInt32BE(28, 0);
  ftypChunk.write('ftyp', 4);
  ftypChunk.write('mmp4', 8);
  ftypChunk.write('isom', 12);
  ftypChunk.write('iso2', 16);
  ftypChunk.write('mp41', 20);
  ftypChunk.write('mp42', 24);

  const mdatChunk1 = Buffer.alloc(8);
  mdatChunk1.writeUInt32BE(8, 0);
  mdatChunk1.write('mdat', 4);

  const mdatChunk2Size = 303739;
  const mdatChunk2 = Buffer.alloc(8 + mdatChunk2Size, 0x01); // I dont know what I need to do on this part
  mdatChunk2.writeUInt32BE(8 + mdatChunk2Size, 0);
  mdatChunk2.write('mdat', 4);

  const moovChunkSize = 6202;
  const moovChunk = Buffer.alloc(8 + moovChunkSize, 0x02); // I dont know what I need to do on this part
  moovChunk.writeUInt32BE(8 + moovChunkSize, 0);
  moovChunk.write('moov', 4);

  passThroughStream.write(ftypChunk);
  passThroughStream.write(mdatChunk1);
  passThroughStream.write(mdatChunk2);
  passThroughStream.write(moovChunk);
  passThroughStream.end();

  for await (const chunk of passThroughStream) {
    yield chunk;
  }

  //@ts-ignore
  for await (const chunk of chunks) {
    yield chunk;
  }
}

我还尝试以这种格式使用此库来与视频片段本身的块共享方法块,但这也没有帮助。

const ffmpegStream = ffmpeg()
    .input(chunks)
    .format('mp4')
    .addOutputOptions(
      '-movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov',
    )
    .on('error', function (err) {
      console.log('An error occurred: ' + err.message);
    })
    .on('end', function () {
      console.log('Processing finished !');
    });

  const ffstream = ffmpegStream.pipe().on('data', function (chunk) {
    console.log('ffmpeg just wrote ' + chunk.length + ' bytes');
  });
node.js amazon-web-services amazon-s3 video-streaming html5-video
1个回答
0
投票

Amazon S3 不会修改视频内容。它存储视频。使用 AWS Elemental MediaConvert 服务执行视频修改。 MediaConvert 是一种基于文件的视频转码服务,可以将媒体文件从一种格式转换为另一种格式、调整大小、添加叠加以及执行其他视频处理任务。

这里有一个相关的 STO -- AWS Elemental MediaConvert Video File 修剪开始和结束持续时间

© www.soinside.com 2019 - 2024. All rights reserved.