使用 MediaRecorder 指定编解码器
Specifying codecs with MediaRecorder
如何指定与 MediaRecorder API? The only option I see is for 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 音频?
Firefox v44.0.2
How can I get Opus audio with VP8 video in a WebM container with the MediaRecorder API?
不幸的是,目前这显然是不可能的。事实上,除了 audio/video 流编解码器之外,目前似乎甚至无法设置 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("")
.
这条评论确实为未来带来了希望:
// 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 错误报告。
查看 Chrome LayoutTests for isTypeSupported()
,那里使用的 mimeType
应该适用于 MediaRecorder
构造函数。
如何指定与 MediaRecorder API? The only option I see is for 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 音频?
Firefox v44.0.2
How can I get Opus audio with VP8 video in a WebM container with the MediaRecorder API?
不幸的是,目前这显然是不可能的。事实上,除了 audio/video 流编解码器之外,目前似乎甚至无法设置 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("")
.
这条评论确实为未来带来了希望:
// 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 错误报告。
查看 Chrome LayoutTests for isTypeSupported()
,那里使用的 mimeType
应该适用于 MediaRecorder
构造函数。