Is it possible to play only the audio from a YouTube video using HTML 5 and Javascript?
This question is related to
javascript
html
audio
youtube
Embed the video player and use CSS to hide the video. If you do it properly you may even be able to hide only the video and not the controls below it.
However, I'd recommend against it, because it will be a violation of YouTube TOS. Use your own server instead if you really want to play only audio.
var vid = "bpt84ceWAY0",_x000D_
audio_streams = {},_x000D_
audio_tag = document.getElementById('youtube');_x000D_
_x000D_
fetch("https://"+vid+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https%3A%2F%2Fwww.youtube.com%2Fget_video_info%3Fvideo_id%3D" + vid).then(response => {_x000D_
if (response.ok) {_x000D_
response.text().then(data => {_x000D_
_x000D_
var data = parse_str(data),_x000D_
streams = (data.url_encoded_fmt_stream_map + ',' + data.adaptive_fmts).split(',');_x000D_
_x000D_
streams.forEach(function(s, n) {_x000D_
var stream = parse_str(s),_x000D_
itag = stream.itag * 1,_x000D_
quality = false;_x000D_
console.log(stream);_x000D_
switch (itag) {_x000D_
case 139:_x000D_
quality = "48kbps";_x000D_
break;_x000D_
case 140:_x000D_
quality = "128kbps";_x000D_
break;_x000D_
case 141:_x000D_
quality = "256kbps";_x000D_
break;_x000D_
}_x000D_
if (quality) audio_streams[quality] = stream.url;_x000D_
});_x000D_
_x000D_
console.log(audio_streams);_x000D_
_x000D_
audio_tag.src = audio_streams['128kbps'];_x000D_
audio_tag.play();_x000D_
})_x000D_
}_x000D_
});_x000D_
_x000D_
function parse_str(str) {_x000D_
return str.split('&').reduce(function(params, param) {_x000D_
var paramSplit = param.split('=').map(function(value) {_x000D_
return decodeURIComponent(value.replace('+', ' '));_x000D_
});_x000D_
params[paramSplit[0]] = paramSplit[1];_x000D_
return params;_x000D_
}, {});_x000D_
}
_x000D_
<audio id="youtube" autoplay controls loop></audio>
_x000D_
It seems in Septeber 2019, YouTube updated the values that are returned by get_video_info
.
Rather than data.url_encoded_fmt_stream_map
and data.adaptive_fmts
(as used in the other older examples) now we are looking for for data.formats
and data.adaptiveFormats
.
Anyways here is what you are all here for some code that loads a YouTube video into an <audio>
element. Try it on CodePen
// YouTube video ID
var videoID = "CMNry4PE93Y";
// Fetch video info (using a proxy to avoid CORS errors)
fetch('https://cors-anywhere.herokuapp.com/' + "https://www.youtube.com/get_video_info?video_id=" + videoID).then(response => {
if (response.ok) {
response.text().then(ytData => {
// parse response to find audio info
var ytData = parse_str(ytData);
var getAdaptiveFormats = JSON.parse(ytData.player_response).streamingData.adaptiveFormats;
var findAudioInfo = getAdaptiveFormats.findIndex(obj => obj.audioQuality);
// get the URL for the audio file
var audioURL = getAdaptiveFormats[findAudioInfo].url;
// update the <audio> element src
var youtubeAudio = document.getElementById('youtube');
youtubeAudio.src = audioURL;
});
}
});
function parse_str(str) {
return str.split('&').reduce(function(params, param) {
var paramSplit = param.split('=').map(function(value) {
return decodeURIComponent(value.replace('+', ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
_x000D_
<audio id="youtube" controls></audio>
_x000D_
// YouTube video ID
var videoID = "CMNry4PE93Y";
// Fetch video info (using a proxy to avoid CORS errors)
fetch('https://cors-anywhere.herokuapp.com/' + "https://www.youtube.com/get_video_info?video_id=" + videoID).then(response => {
if (response.ok) {
response.text().then(ytData => {
// parse response to find audio info
var ytData = parse_str(ytData);
var getAdaptiveFormats = JSON.parse(ytData.player_response).streamingData.adaptiveFormats;
var findAudioInfo = getAdaptiveFormats.findIndex(obj => obj.audioQuality);
// get the URL for the audio file
var audioURL = getAdaptiveFormats[findAudioInfo].url;
// update the <audio> element src
var youtubeAudio = document.getElementById('youtube');
youtubeAudio.src = audioURL;
});
}
});
function parse_str(str) {
return str.split('&').reduce(function(params, param) {
var paramSplit = param.split('=').map(function(value) {
return decodeURIComponent(value.replace('+', ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
_x000D_
<audio id="youtube" controls></audio>
_x000D_
You can parse Youtube meta file for all streams available for this particular video id using this link: https://www.youtube.com/get_video_info?video_id={VID}
and extract audio only streams.
Here is an example with public Google Image proxy (but you can use any free or your own CORS
proxy):
var vid = "3r_Z5AYJJd4",_x000D_
audio_streams = {},_x000D_
audio_tag = document.getElementById('youtube');_x000D_
_x000D_
fetch("https://"+vid+"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https%3A%2F%2Fwww.youtube.com%2Fget_video_info%3Fvideo_id%3D" + vid).then(response => {_x000D_
if (response.ok) {_x000D_
response.text().then(data => {_x000D_
_x000D_
var data = parse_str(data),_x000D_
streams = (data.url_encoded_fmt_stream_map + ',' + data.adaptive_fmts).split(',');_x000D_
_x000D_
streams.forEach(function(s, n) {_x000D_
var stream = parse_str(s),_x000D_
itag = stream.itag * 1,_x000D_
quality = false;_x000D_
console.log(stream);_x000D_
switch (itag) {_x000D_
case 139:_x000D_
quality = "48kbps";_x000D_
break;_x000D_
case 140:_x000D_
quality = "128kbps";_x000D_
break;_x000D_
case 141:_x000D_
quality = "256kbps";_x000D_
break;_x000D_
}_x000D_
if (quality) audio_streams[quality] = stream.url;_x000D_
});_x000D_
_x000D_
console.log(audio_streams);_x000D_
_x000D_
audio_tag.src = audio_streams['128kbps'];_x000D_
audio_tag.play();_x000D_
})_x000D_
}_x000D_
});_x000D_
_x000D_
function parse_str(str) {_x000D_
return str.split('&').reduce(function(params, param) {_x000D_
var paramSplit = param.split('=').map(function(value) {_x000D_
return decodeURIComponent(value.replace('+', ' '));_x000D_
});_x000D_
params[paramSplit[0]] = paramSplit[1];_x000D_
return params;_x000D_
}, {});_x000D_
}
_x000D_
<audio id="youtube" autoplay controls loop></audio>
_x000D_
Doesn't work for all videos, very depends on monetization settings or something like that.
I agree with Tom van der Woerdt. You could use CSS to hide the video (visibility:hidden or overflow:hidden in a div wrapper constrained by height), but that may violate Youtube's policies. Additionally, how could you control the audio (pause, stop, volume, etc.)?
You could instead turn to resources such as http://www.houndbite.com/ to manage audio.
The answer is simple: Use a 3rd party product like jwplayer or similar, then set it to the minimal player size which is the audio player size (only shows player controls).
Voila.
Been using this for over 8 years.
This may be an old post but people could still be searching for this so here you go:
<div style="position:relative;width:267px;height:25px;overflow:hidden;">
<div style="position:absolute;top:-276px;left:-5px">
<iframe width="300" height="300"
src="https://www.youtube.com/embed/youtubeID?rel=0">
</iframe>
</div>
</div>
Adding to the mentions of jwplayer and possible TOS violations, I would like to to link to the following repository on github: YouTube Audio Player Generation Library, that allows to generate the following output:
Library has the support for the playlists and PHP autorendering given the video URL and the configuration options.
VIDEO_ID with actual ID of your YouTube video.
<div data-video="VIDEO_ID"
data-autoplay="0"
data-loop="1"
id="youtube-audio">
</div>
<script src="https://www.youtube.com/iframe_api"></script>
<script src="https://cdn.rawgit.com/labnol/files/master/yt.js"></script>
Source: Stackoverflow.com