웹 애플리케이션에서 오디오 출력 대상 전환
소개
음성 출력을 다루는 웹 응용 프로그램을 만들면 음성 출력 대상을 전환하고 싶지 않습니까?
이 기사에서는 Google 크롬 한정으로 기능을 구현하는 방법을 소개합니다.
전제 조건
데모
여기에서 동작을 확인할 수 있습니다.
구현 방법
음성 출력 장치의 정보 수집
MediaDevices.enumerateDevices() 을 이용합니다.
navigator.mediaDevices.enumerateDevices()
.then(function (devices) { // success
}).catch(function (error) { // error
return;
});
실행할 때 사용할 수 있는 I/O 미디어 장치에 대한 정보가 있는 MediaDeviceInfo 개체가 배열에서 반환됩니다.
내 환경에서 실행하면 다음과 같은 배열이 반환됩니다. 어떤 디스플레이를 사용하고 있든, 카메라를 사용하고 있다는 것도 알 수 있습니다 w
kind에 주목하십시오. audiooutput이 되고 있는 디바이스가 음성 출력 디바이스입니다. 이 정보를 이용합니다.
사용자가 기기를 선택하도록 합니다.
SkyWay의 공식 샘플 코드에는 이미 오디오 및 비디오 입력 소스를 선택하는 코드가 들어 있습니다. 이번에는 거기에 음성 출력처를 전환하는 코드도 추기합니다.
const audioSelect = $('#audioSource');
const videoSelect = $('#videoSource');
const audioDeviceSelect = $('#audioDevice'); // 追記
selectors = [audioSelect, videoSelect, audioDeviceSelect]; // 修正
navigator.mediaDevices.enumerateDevices()
.then(deviceInfos => {
const values = selectors.map(select => select.val() || '');
selectors.forEach(select => {
const children = select.children(':first');
while (children.length) {
select.remove(children);
}
});
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = $('<option>').val(deviceInfo.deviceId);
if (deviceInfo.kind === 'audioinput') {
option.text(deviceInfo.label ||
'Microphone ' + (audioSelect.children().length + 1));
audioSelect.append(option);
} else if (deviceInfo.kind === 'videoinput') {
option.text(deviceInfo.label ||
'Camera ' + (videoSelect.children().length + 1));
videoSelect.append(option);
} else if (deviceInfo.kind === 'audiooutput') { // ここから追記
option.text(deviceInfo.label ||
'Output device ' + (audioDeviceSelect.children().length + 1));
audioDeviceSelect.append(option);
} // ここまで追記
}
selectors.forEach((select, selectorIndex) => {
if (Array.prototype.slice.call(select.children()).some(n => {
return n.value === values[selectorIndex];
})) {
select.val(values[selectorIndex]);
}
});
videoSelect.on('change', step1);
audioSelect.on('change', step1);
audioDeviceSelect.on('change', step1); // 追記
});
수정할 위치와 추가할 위치는 댓글과 같습니다.
음성 출력 대상 전환
HTMLMediaElement.setSinkId() 을 이용합니다.
const audio = document.createElement('audio');
audio.setSinkId(deviceId);
MediaDevices.enumerateDevices()로 취득한 음성 출력 디바이스의 deviceId를 인수로서 주는 것으로, 음성 출력 디바이스를 전환할 수 있습니다.
이번에는 이렇게 이용하고 있습니다.
if(audioDevice){
$('#their-video').get(0).setSinkId(audioDevice);
}
deviceId가 null의 경우는 에러가 나오므로, if문으로 미리 체크하고 있습니다.
실행해보기
이렇게 전환할 수 있습니다. 물론 화상 채팅 중에 동적으로 전환할 수도 있습니다.
여담 MediaDevices.enumerateDevices() 실행 타이밍
Chrome과 Firefox 모두 MediaDevices.getUserMedia()에서 사용자가 카메라와 마이크 사용을 허용하지 않으면 labe 값을 얻을 수 없습니다.
이번에 다룬 음성 출력 디바이스의 정보에 대해서는, 마이크의 이용을 허가하지 않으면 다음과 같이 비워집니다.
label의 값은 UI에 출력하고 싶네요. 그런 때는, MediaDevices.getUserMedia() → 유저의 액션 → MediaDevices.enumerateDevices() 라고 하는 차례로 실행하는 것으로, 해결할 수 있습니다. Firefox는 이전부터 이러한 거동이었지만, Chrome은 최근(동료에게 조사해 주었더니 아마 M66으로부터) 이런 거동이 되고 있는 것 같으므로, 주의해 주세요. 그 전에는 사용자의 허가 없이 label 정보를 취득할 수 있었습니다.
또한 SkyWay의 공식 샘플은 사용자가 허가하기 전에 MediaDevices.enumerateDevices()를 실행하기 때문에 처음 액세스할 때는 label 정보를 얻을 수 없습니다. 이번 데모에서는 잠정적으로 그 부분을 수정하고 있습니다.
Reference
이 문제에 관하여(웹 애플리케이션에서 오디오 출력 대상 전환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yusuke84/items/74f34ab16efc6dd0eb94
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
음성 출력 장치의 정보 수집
MediaDevices.enumerateDevices() 을 이용합니다.
navigator.mediaDevices.enumerateDevices()
.then(function (devices) { // success
}).catch(function (error) { // error
return;
});
실행할 때 사용할 수 있는 I/O 미디어 장치에 대한 정보가 있는 MediaDeviceInfo 개체가 배열에서 반환됩니다.
내 환경에서 실행하면 다음과 같은 배열이 반환됩니다. 어떤 디스플레이를 사용하고 있든, 카메라를 사용하고 있다는 것도 알 수 있습니다 w
kind에 주목하십시오. audiooutput이 되고 있는 디바이스가 음성 출력 디바이스입니다. 이 정보를 이용합니다.
사용자가 기기를 선택하도록 합니다.
SkyWay의 공식 샘플 코드에는 이미 오디오 및 비디오 입력 소스를 선택하는 코드가 들어 있습니다. 이번에는 거기에 음성 출력처를 전환하는 코드도 추기합니다.
const audioSelect = $('#audioSource');
const videoSelect = $('#videoSource');
const audioDeviceSelect = $('#audioDevice'); // 追記
selectors = [audioSelect, videoSelect, audioDeviceSelect]; // 修正
navigator.mediaDevices.enumerateDevices()
.then(deviceInfos => {
const values = selectors.map(select => select.val() || '');
selectors.forEach(select => {
const children = select.children(':first');
while (children.length) {
select.remove(children);
}
});
for (let i = 0; i !== deviceInfos.length; ++i) {
const deviceInfo = deviceInfos[i];
const option = $('<option>').val(deviceInfo.deviceId);
if (deviceInfo.kind === 'audioinput') {
option.text(deviceInfo.label ||
'Microphone ' + (audioSelect.children().length + 1));
audioSelect.append(option);
} else if (deviceInfo.kind === 'videoinput') {
option.text(deviceInfo.label ||
'Camera ' + (videoSelect.children().length + 1));
videoSelect.append(option);
} else if (deviceInfo.kind === 'audiooutput') { // ここから追記
option.text(deviceInfo.label ||
'Output device ' + (audioDeviceSelect.children().length + 1));
audioDeviceSelect.append(option);
} // ここまで追記
}
selectors.forEach((select, selectorIndex) => {
if (Array.prototype.slice.call(select.children()).some(n => {
return n.value === values[selectorIndex];
})) {
select.val(values[selectorIndex]);
}
});
videoSelect.on('change', step1);
audioSelect.on('change', step1);
audioDeviceSelect.on('change', step1); // 追記
});
수정할 위치와 추가할 위치는 댓글과 같습니다.
음성 출력 대상 전환
HTMLMediaElement.setSinkId() 을 이용합니다.
const audio = document.createElement('audio');
audio.setSinkId(deviceId);
MediaDevices.enumerateDevices()로 취득한 음성 출력 디바이스의 deviceId를 인수로서 주는 것으로, 음성 출력 디바이스를 전환할 수 있습니다.
이번에는 이렇게 이용하고 있습니다.
if(audioDevice){
$('#their-video').get(0).setSinkId(audioDevice);
}
deviceId가 null의 경우는 에러가 나오므로, if문으로 미리 체크하고 있습니다.
실행해보기
이렇게 전환할 수 있습니다. 물론 화상 채팅 중에 동적으로 전환할 수도 있습니다.
여담 MediaDevices.enumerateDevices() 실행 타이밍
Chrome과 Firefox 모두 MediaDevices.getUserMedia()에서 사용자가 카메라와 마이크 사용을 허용하지 않으면 labe 값을 얻을 수 없습니다.
이번에 다룬 음성 출력 디바이스의 정보에 대해서는, 마이크의 이용을 허가하지 않으면 다음과 같이 비워집니다.
label의 값은 UI에 출력하고 싶네요. 그런 때는, MediaDevices.getUserMedia() → 유저의 액션 → MediaDevices.enumerateDevices() 라고 하는 차례로 실행하는 것으로, 해결할 수 있습니다. Firefox는 이전부터 이러한 거동이었지만, Chrome은 최근(동료에게 조사해 주었더니 아마 M66으로부터) 이런 거동이 되고 있는 것 같으므로, 주의해 주세요. 그 전에는 사용자의 허가 없이 label 정보를 취득할 수 있었습니다.
또한 SkyWay의 공식 샘플은 사용자가 허가하기 전에 MediaDevices.enumerateDevices()를 실행하기 때문에 처음 액세스할 때는 label 정보를 얻을 수 없습니다. 이번 데모에서는 잠정적으로 그 부분을 수정하고 있습니다.
Reference
이 문제에 관하여(웹 애플리케이션에서 오디오 출력 대상 전환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/yusuke84/items/74f34ab16efc6dd0eb94
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Chrome과 Firefox 모두 MediaDevices.getUserMedia()에서 사용자가 카메라와 마이크 사용을 허용하지 않으면 labe 값을 얻을 수 없습니다.
이번에 다룬 음성 출력 디바이스의 정보에 대해서는, 마이크의 이용을 허가하지 않으면 다음과 같이 비워집니다.
label의 값은 UI에 출력하고 싶네요. 그런 때는, MediaDevices.getUserMedia() → 유저의 액션 → MediaDevices.enumerateDevices() 라고 하는 차례로 실행하는 것으로, 해결할 수 있습니다. Firefox는 이전부터 이러한 거동이었지만, Chrome은 최근(동료에게 조사해 주었더니 아마 M66으로부터) 이런 거동이 되고 있는 것 같으므로, 주의해 주세요. 그 전에는 사용자의 허가 없이 label 정보를 취득할 수 있었습니다.
또한 SkyWay의 공식 샘플은 사용자가 허가하기 전에 MediaDevices.enumerateDevices()를 실행하기 때문에 처음 액세스할 때는 label 정보를 얻을 수 없습니다. 이번 데모에서는 잠정적으로 그 부분을 수정하고 있습니다.
Reference
이 문제에 관하여(웹 애플리케이션에서 오디오 출력 대상 전환), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/yusuke84/items/74f34ab16efc6dd0eb94텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)