firefox - 使用 MediaRecorder 指定编解码器

标签 firefox webrtc web-audio-api web-mediarecorder mediarecorder-api

如何指定 MediaRecorder API 使用的编解码器?我看到的唯一选项是 mimeType这还不够。在 mimeType 选项中塞入编解码器似乎不起作用。

var mediaRecorder = new MediaRecorder(
    outputMediaStream
  ),
  {
    mimeType: 'video/webm; codecs="opus,vp8"'
  }
);

这会产生带有 Vorbis 和 VP8 的 WebM 流:

FFMPEG STDERR: Input #0, matroska,webm, from 'pipe:':
  Metadata:
    encoder         : QTmuxingAppLibWebM-0.0.1
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0(eng): Video: vp8, yuv420p, 640x360, SAR 1:1 DAR 16:9, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
    Stream #0:1(eng): Audio: vorbis, 44100 Hz, stereo, fltp (default)

如果我制作一个只有音轨(无视频)的 MediaStream,则 MediaRecorder 在 Ogg 容器中输出 Opus 音频:

FFMPEG STDERR: Input #0, ogg, from 'pipe:':
  Duration: N/A, start: 0.000000, bitrate: N/A
    Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp
    Metadata:
      ENCODER         : Mozilla44.0.2

如何使用 MediaRecorder API 在 WebM 容器中获取带有 VP8 视频的 Opus 音频?

火狐 v44.0.2

最佳答案

How can I get Opus audio with VP8 video in a WebM container with the MediaRecorder API?

不幸的是,目前这显然是不可能的。事实上,除了音频/视频流编解码器之外,目前似乎甚至无法设置 mimetype。 Firefox 根据请求的流决定使用可用的编码器,而 JavaScript API 在这方面没有提供太多发言权。

一如既往,证据就在源头。

这里是从 mimetype 初始化编码的地方。

Excerpt from dom/media/MediaRecorder.cpp :

    // Allocate encoder and bind with union stream.
    // At this stage, the API doesn't allow UA to choose the output mimeType format.

    // Make sure the application has permission to assign AUDIO_3GPP
    if (mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP) && CheckPermission("audio-capture:3gpp")) {
      mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(AUDIO_3GPP),
                                             mRecorder->GetAudioBitrate(),
                                             mRecorder->GetVideoBitrate(),
                                             mRecorder->GetBitrate(),
                                             aTrackTypes);
    } else if (mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP2) && CheckPermission("audio-capture:3gpp2")) {
      mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(AUDIO_3GPP2),
                                             mRecorder->GetAudioBitrate(),
                                             mRecorder->GetVideoBitrate(),
                                             mRecorder->GetBitrate(),
                                             aTrackTypes);
    } else {
      mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""),
                                             mRecorder->GetAudioBitrate(),
                                             mRecorder->GetVideoBitrate(),
                                             mRecorder->GetBitrate(),
                                             aTrackTypes);
    }

我们可以看到,除了 3GPP* mime 之外,传递给 CreateEncoded 的 mimetype 是一个空字符串 NS_LITERAL_STRING("")

此评论确实为 future 带来了希望:

// At this stage, the API doesn't allow UA to choose the output mimeType format.

Excerpts from dom/media/encoder/MediaEncoder.cpp :

启用 WebM 的视频的第一个案例。

  else if (MediaEncoder::IsWebMEncoderEnabled() &&
          (aMIMEType.EqualsLiteral(VIDEO_WEBM) ||
          (aTrackTypes & ContainerWriter::CREATE_VIDEO_TRACK))) {
    if (aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK) {
      audioEncoder = new VorbisTrackEncoder();
      NS_ENSURE_TRUE(audioEncoder, nullptr);
    }
    videoEncoder = new VP8TrackEncoder();
    writer = new WebMWriter(aTrackTypes);
    NS_ENSURE_TRUE(writer, nullptr);
    NS_ENSURE_TRUE(videoEncoder, nullptr);
    mimeType = NS_LITERAL_STRING(VIDEO_WEBM);
  }

仅启用 OGG 的音频的最终情况。

  else if (MediaDecoder::IsOggEnabled() && MediaDecoder::IsOpusEnabled() &&
           (aMIMEType.EqualsLiteral(AUDIO_OGG) ||
           (aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK))) {
    writer = new OggWriter();
    audioEncoder = new OpusTrackEncoder();
    NS_ENSURE_TRUE(writer, nullptr);
    NS_ENSURE_TRUE(audioEncoder, nullptr);
    mimeType = NS_LITERAL_STRING(AUDIO_OGG);
  }

根据这段代码,我认为我们可以得出结论,目前这是不可能的,但它似乎确实在路线图上。

@jib找到以下相关的 Mozilla 错误报告。

关于firefox - 使用 MediaRecorder 指定编解码器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35466078/

相关文章:

python - 信令服务器性能问题 : Python vs NodeJS

javascript - 在 HTML5 WebAudio 中如何知道声音是否停止或播放完毕?

javascript - Web Audio API 声音交互在一段时间后停止工作

css - 在 DOM 检查器中查找计算样式 "source"("trigger")

CSS - Mozilla 错误?框阴影 :inset not working properly

webrtc - 可编程 api twilio : Can browser client join multiple rooms at same time

WebRTC - 浏览器不要求本地 html 文件的麦克风访问权限

javascript - 在网络音频中,为什么 contextTime 比 baseLatency 滞后 currentTime?

javascript - firefox 下载属性不起作用

CSS 转换不起作用 Firefox for XML 文档转换为使用 XSLT 的 HTML