ForeverSc / web-demuxer

Demux media files in the browser using WebAssembly, designed for WebCodecs 在浏览器中实现媒体文件的解封装,专为WebCodecs设计
https://foreversc.github.io/web-demuxer/
MIT License
35 stars 2 forks source link

Playing an Audio Track #7

Closed juntaosun closed 1 week ago

juntaosun commented 2 months ago

Very nice project. Could you update the "Play Video" example to include an example that plays the video sound (audio track)? That would be great~


非常好的项目。 您可以在“Play Video”示例中,更新增加一个同步播放视频声音(音频轨道)的示例吗? 这样就太好了~

ForeverSc commented 2 months ago

可以先参考下WebCodecs同时播放音视频的样例,把mp4box.js换成web-demuxer就可以了。后续有空我再加下或者也欢迎提个PR

juntaosun commented 2 months ago

前面的初始化 AudioDecoder 配置流程,configure都显示 state 成功了 configured! {codec: 'mp4a.40.2', sampleRate: 44100, numberOfChannels: 2, description: Uint8Array(5)} 但到了音频解码这一步:

          const audioChunk = demuxer.genEncodedAudioChunk(value);
          audioDecoder.decode(audioChunk);

audioDecoder.decode 方法调试也是存在的,audioChunk 也是有数据,可执行会报错。 Failed to execute 'decode' on 'AudioDecoder': Cannot call 'decode' on a closed codec

我没能跑通音频播放~ 不知是哪里没做对

juntaosun commented 2 months ago
// 读取视频
const reader = demuxer.readAVPacket(startTime, endTime).getReader()

(1)这条读取返回的是视频数据 , 查看默认参数是 streamType=AVMediaType.AVMEDIA_TYPE_VIDEO

(2)为了返回音频,我在后面加了一条

// 读取音频
const audioReader = demuxer.readAVPacket(startTime, endTime, 1).getReader();

但音频 audioReader.read()....不会触发。 【问题】除非把前面的视频 reader.read().... 注释,音频才会触发。(两个只能触发其中一个) 此时可以播放声音,但因为读取视频部份注释了,没画面。


// reader 
const reader = demuxer.readAVPacket(startTime, endTime).getReader()
// 要是能同时返回视频或音频,(带上streamType进行分数据区分?)
 reader.read().then(async function processPacket({ done, value , streamType }) {
// 或者 value.streamType ?

🧸暂时没搞定,等待作者指导一下,如何正确同时处理视频和音频。

juntaosun commented 2 months ago

完整测试代码:


        // 读取视频
        const reader = demuxer.readAVPacket(startTime, endTime).getReader()

        reader.read().then(async function processPacket({ done, value }) {
          if (done) {
            decoder.flush();
            console.log('video read finished');
            return
          }

          //视频解码
          const videoChunk = demuxer.genEncodedVideoChunk(value);
          decoder.decode(videoChunk);

          await wait(1000 / 30) // 30fps, wait for frame decode and draw

          return reader.read().then(processPacket)
        });

        // 读取音频, 参数为:1 = AVMediaType.AVMEDIA_TYPE_AUDIO
        const audioReader = demuxer.readAVPacket(startTime, endTime, 1).getReader();

        audioReader.read().then(async function processPacketAudio({ done, value }) {
          // 问题所在:这里面不会触发,除非注释掉上面的视频部份 ?
          if (done) {
            //audioDecoder.flush();
            console.log('audio read finished');
            return
          }

          //不会触发
          console.log("音频数据:",value);

          // 音频解码
          //const audioChunk = demuxer.genEncodedAudioChunk(value);
          //audioDecoder.decode(audioChunk);

          await wait(1000 / 30) // 30fps, wait for frame decode and draw

          return audioReader.read().then(processPacketAudio)
        });
ForeverSc commented 2 months ago

因为readAVPacket会占用worker,导致另外一个无法执行。可以再创建一个demuxer,专门给音频用,这样就会新建一个worker,互相不影响。

ForeverSc commented 2 months ago

后续我再补充个同时读取的方法

juntaosun commented 3 weeks ago

Hi, any latest progress on audio track syncing?

ForeverSc commented 3 weeks ago

因为readAVPacket会占用worker,导致另外一个无法执行。可以再创建一个demuxer,专门给音频用,这样就会新建一个worker,互相不影响。

@juntaosun 有试过这个方法么?想了下同时读取会让API有些意义模糊不清,还是分开处理会好些