Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a media stream of the speaker's output to transfer it over the network or record it?

I'm trying to get the output of the speaker and then do what ever I want with this stream .

I tried to use this to get the speaker's stream:

var mySpeakerStream = new MediaStream();
navigator.mediaDevices.getUserMedia({audio: {deviceId : {exact: mySpeakerId} } }).then(s => {        
        myStream.addTrack(s.getAudioTracks()[0]);
}).catch( console.log('failed') );

I expected to get the speaker but I did not , then I realised that the getUserMedia method returns a MediaStream of an input device only. Is there any way to get a stream of the speaker's output?

like image 403
Al-Shahhoud Baraa Avatar asked Oct 31 '19 13:10

Al-Shahhoud Baraa


2 Answers

JavaScript media devices behave exactly in the same way as the system audio devices. If you are able to record the device in something like Audacity (or any sound recorder), you will be able to record the device in JavaScript using a media device.

However, getting access to the speaker's output requires set up on the operating system of the computer - probably for security, amongst other reasons.

This can be done by creating an audio loopback device on the operating system, but creating the loopback can't be done purely via client-side JavaScript, as of October 2019.

like image 118
Greg Avatar answered Oct 11 '22 23:10

Greg


after more thinking about the issue I found that: I can use getDisplyMedia method but it doesn't support audio only requests, so I tried to get the stream of both audio and video then I get the audio tracks out of it just like this:

var speaker = new MediaStream;
if (navigator.getDisplayMedia) {
    navigator.getDisplayMedia({
        video: true ,
        audio: true
    }).then(stream => {
        speaker.addTrack(stream.getAudioTracks()[0].clone());
        // stopping and removing the video track to enhance the performance
        stream.getVideoTracks()[0].stop();
        stream.removeTrack(stream.getVideoTracks()[0]);
    }).catch(() => {
        console.error('failed')
    });
} else if (navigator.mediaDevices.getDisplayMedia) {
    navigator.mediaDevices.getDisplayMedia({
        video: true ,
        audio: true
    }).then(stream => {
        speaker.addTrack(stream.getAudioTracks()[0].clone());
        // stopping and removing the video track to enhance the performance
        stream.getVideoTracks()[0].stop();
        stream.removeTrack(stream.getVideoTracks()[0]);
    }).catch(() => {
        console.error('failed')
    });
}

I know that does not solve the issue perfectly but I think it's useful .

'still working and waiting for more solutions'

like image 29
Al-Shahhoud Baraa Avatar answered Oct 12 '22 00:10

Al-Shahhoud Baraa