【问题标题】:How to choose input video device for webrtc?如何为 webrtc 选择输入视频设备?
【发布时间】:2013-01-30 18:18:43
【问题描述】:

我正在研究 webRTC 应用程序。

我的参考是这个软件

apprtc https://code.google.com/p/webrtc/source/browse/trunk/samples/js/apprtc/

演示 https://apprtc.appspot.com/

我的电脑有内置视频设备,apprtc 使用这个视频设备。 不过我想改用 USB 摄像机。

我正在寻找更改输入视频设备的方法。 但我在源文件中找不到任何线索。

有人知道吗?

【问题讨论】:

  • 一般情况下,当您第一次加载页面时,它会询问您是否允许使用设备,您可以从下拉菜单中选择您要使用的设备。你没有那个选项吗?你用的是什么浏览器?
  • 要从 javascript 执行此操作,答案如下:stackoverflow.com/questions/20076377

标签: webrtc


【解决方案1】:

在 Chrome 上:

chrome://settings/content/camera
chrome://settings/content/microphone

在 Firefox 上: media.navigator.permission.disabled=false

【讨论】:

  • 我能问一下Chrome的版本吗,我的版本是24.0.1312.57。但是我的没有麦克风,相机选择标签在“媒体”
  • 抱歉,这是 chrome canary。在 chrome stable 上,我找不到这样的选项。但是当网页尝试访问相机时,我仍然可以从通知栏中选择相机。
  • 我可以找到你所说的设备选择菜单。感谢 Muaz 解决了这个问题!!
  • 我一开始还以为是脚本可以控制的,这个webRTC的设计有点失望
  • 在移动设备上呢?我在 chrome mobile (vanilla Android 4.3, Chrome 28) 中找不到这个菜单
【解决方案2】:

试试这个捕获所有音频/视频输入设备的演示:

https://www.webrtc-experiment.com/demos/MediaStreamTrack.getSources.html

您可以使用相同的 API 捕获任何“特定”设备。

2014 年 3 月 1 日编辑:

MediaStreamTrack.getSources(function (media_sources) {
    for (var i = 0; i < media_sources.length; i++) {
        var media_source = media_sources[i];
        var constraints = {};

        // if audio device
        if (media_source.kind == 'audio') {
            constraints.audio = {
                optional: [{
                    sourceId: media_source.id
                }]
            };
        }

        // if video device
        if (media_source.kind == 'video') {
            constraints.video = {
                optional: [{
                    sourceId: media_source.id
                }]
            };
        }


        // invoke getUserMedia to capture this device
        navigator.webkitGetUserMedia(constraints, function (stream) {
            console.log(stream.id, stream);
        }, console.error);
    }
});

2015 年 9 月 5 日更新:

现在 Microsoft Edge、Chrome 44+、Firefox 38+,所有这些浏览器都支持navigator.mediaDevices.enumerateDevices API。

这是一个可重用的脚本,它为所有这些媒体源 API 提供跨浏览器 shim。它甚至可以在旧版 chrome(43 岁及以上)中工作(甚至在 Android 设备上):

if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
    // Firefox 38+, Microsoft Edge, and Chrome 44+ seems having support of enumerateDevices
    navigator.enumerateDevices = function(callback) {
        navigator.mediaDevices.enumerateDevices().then(callback);
    };
}

function getAllAudioVideoDevices(successCallback, failureCallback) {
    if (!navigator.enumerateDevices && window.MediaStreamTrack && window.MediaStreamTrack.getSources) {
        navigator.enumerateDevices = window.MediaStreamTrack.getSources.bind(window.MediaStreamTrack);
    }

    if (!navigator.enumerateDevices && navigator.mediaDevices.enumerateDevices) {
        navigator.enumerateDevices = navigator.mediaDevices.enumerateDevices.bind(navigator);
    }

    if (!navigator.enumerateDevices) {
        failureCallback(null, 'Neither navigator.mediaDevices.enumerateDevices NOR MediaStreamTrack.getSources are available.');
        return;
    }

    var allMdiaDevices = [];
    var allAudioDevices = [];
    var allVideoDevices = [];

    var audioInputDevices = [];
    var audioOutputDevices = [];
    var videoInputDevices = [];
    var videoOutputDevices = [];

    navigator.enumerateDevices(function(devices) {
        devices.forEach(function(_device) {
            var device = {};
            for (var d in _device) {
                device[d] = _device[d];
            }

            // make sure that we are not fetching duplicate devics
            var skip;
            allMdiaDevices.forEach(function(d) {
                if (d.id === device.id) {
                    skip = true;
                }
            });

            if (skip) {
                return;
            }

            // if it is MediaStreamTrack.getSources
            if (device.kind === 'audio') {
                device.kind = 'audioinput';
            }

            if (device.kind === 'video') {
                device.kind = 'videoinput';
            }

            if (!device.deviceId) {
                device.deviceId = device.id;
            }

            if (!device.id) {
                device.id = device.deviceId;
            }

            if (!device.label) {
                device.label = 'Please invoke getUserMedia once.';
            }

            if (device.kind === 'audioinput' || device.kind === 'audio') {
                audioInputDevices.push(device);
            }

            if (device.kind === 'audiooutput') {
                audioOutputDevices.push(device);
            }

            if (device.kind === 'videoinput' || device.kind === 'video') {
                videoInputDevices.push(device);
            }

            if (device.kind.indexOf('audio') !== -1) {
                allAudioDevices.push(device);
            }

            if (device.kind.indexOf('video') !== -1) {
                allVideoDevices.push(device);
            }

            // there is no 'videoouput' in the spec.
            // so videoOutputDevices will always be [empty]

            allMdiaDevices.push(device);
        });

        if (successCallback) {
            successCallback({
                allMdiaDevices: allMdiaDevices,
                allVideoDevices: allVideoDevices,
                allAudioDevices: allAudioDevices,
                videoInputDevices: videoInputDevices,
                audioInputDevices: audioInputDevices,
                audioOutputDevices: audioOutputDevices
            });
        }
    });
}

以下是如何使用上述可重复使用的跨浏览器 shim:

getAllAudioVideoDevices(function(result) {
    if (result.allMdiaDevices.length) {
        console.debug('Number of audio/video devices available:', result.allMdiaDevices.length);
    }

    if (result.allVideoDevices.length) {
        console.debug('Number of video devices available:', result.allVideoDevices.length);
    }

    if (result.allAudioDevices.length) {
        console.debug('Number of audio devices available:', result.allAudioDevices.length);
    }

    if (result.videoInputDevices.length) {
        console.debug('Number of video-input devices available:', result.videoInputDevices.length);
    }

    if (result.audioInputDevices.length) {
        console.debug('Number of audio-input devices available:', result.audioInputDevices.length);
    }

    if (result.audioOutputDevices.length) {
        console.debug('Number of audio-output devices available:', result.audioOutputDevices.length);
    }

    if (result.allMdiaDevices.length && result.allMdiaDevices[0].label === 'Please invoke getUserMedia once.') {
        console.warn('It seems you did not invoke navigator-getUserMedia before using these API.');
    }

    console.info('All audio input devices:');
    result.audioInputDevices.forEach(function(device) {
        console.log('Audio input device id:', device.id, 'Device label:', device.label);
    });

    console.info('All audio output devices:');
    result.audioOutputDevices.forEach(function(device) {
        console.log('Audio output device id:', device.id, 'Device label:', device.label);
    });

    console.info('All video input devices:');
    result.videoInputDevices.forEach(function(device) {
        console.log('Video input device id:', device.id, 'Device label:', device.label);
    });
}, function(error) {
    alert(error);
});

【讨论】:

  • 嘿 Muaz,我认为您需要在 getMediaDevices 中关闭。看起来每次都捕获了同一个麦克风(您可以知道,因为所有麦克风的索引都与数组中的最后一个索引相同。希望这会有所帮助。此外,为了使其成为更好的 Stack Overflow 答案,您应该真正编辑此内容并将代码包含在您的帖子正文中。如果您的链接中断,则此答案对未来的访问者毫无用处。希望这会有所帮助。
  • 感谢您的编辑和出色、有用的演示! MediaStreamTrack.getSources 完全按照我希望的方式工作。 +1
  • @Muaz khan。当我遵循上述方法时,我收到此错误:无法在“MediaStreamTrack”上执行“getSources”:无法在“MediaStreamTrack”上执行“getSources”:功能尚未实现。这是否意味着它尚未实施?
  • 你可能在安卓上使用 chrome-beta;或者您使用的是 Firefox,或者您使用的是 chrome M30 或更早版本。据我所知,这些 API 在 chromium 中是受支持的。也许你启用了:chrome://flags/#disable-device-enumeration 这个标志默认是禁用的。
  • @Chiwda 感谢您的提醒——我已经有一段时间没有看这个例子了。会修! webrtc.github.io/samples 有使用新 API/方法/语法的演示。
【解决方案3】:

事实证明,Chrome 确实支持允许您执行此操作的 MediaStreamTrack API。在 Firefox 中,API 仍处于试验阶段。这是 Chrome 的实现:

if (typeof MediaStreamTrack === 'undefined'){
  alert('This browser does not support MediaStreamTrack.\n\nTry Chrome Canary.');
} else {
  MediaStreamTrack.getSources( onSourcesAcquired);
}

function onSourcesAcquired(sources) {
  for (var i = 0; i != sources.length; ++i) {
    var source = sources[i];
    // source.id -> DEVICE ID
    // source.label -> DEVICE NAME
    // source.kind = "audio" OR "video"
    // TODO: add this to some datastructure of yours or a selection dialog
  }
}

....

And then when calling getUserMedia, specify the id in the constraints:

var constraints = {
  audio: {
    optional: [{sourceId: selected_audio_source_id}]
  },
  video: {
    optional: [{sourceId: selected_video_source_id}]
  }
};
navigator.getUserMedia(constraints, onSuccessCallback, onErrorCallback);

【讨论】:

    【解决方案4】:

    听起来你正在寻找facingMode。您可以在此文档中查看: http://www.w3.org/TR/2013/WD-mediacapture-streams-20130516/#idl-def-AllVideoCapabilities

    虽然还不确定它的支持程度。

    【讨论】:

    • 据我所知,尚不支持任何浏览器,但已计划实施。
    • 更新: facingMode 可用于 Android 版 Firefox(自 26 起),现在可用于 Android 版 Chrome 的 adapter.js polyfill。请参阅this answer to a similar question 中的演示。
    猜你喜欢
    • 2017-05-25
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多