thelevicole / youtube-to-html5-loader

Load YouTube videos with the HTLML5 <video> element without needing iframes or the YouTube JS API.
https://thelevicole.com/youtube-to-html5-loader/
133 stars 25 forks source link

Videos have no sound! #4

Closed Christof0007 closed 3 years ago

Christof0007 commented 3 years ago

All projects versions beyond version 2.0.0, have no sound for the videos. Even your demo's on your website have the same problem.

Doesn't matter which browser you use. The only way I can botch the problem, is to use the v2.0.0 YouTubeToHtml5.js file.

Any ideas please?

P.S. Great project by the way :-)

Christof0007 commented 3 years ago

Fairly sure this is due to the videos set to AutoPlay="True"

Browsers are set to be mute as default I believe, to stop spam and adverts.

Update: Interesting find today, purely by chance.

Now on my 2nd Win7 PC (work PC), I've just used this video as a demonstration (defaults to 720p): https://www.youtube.com/watch?v=rJ9RI1XSoWs

To my surprise, I got sound ('YES SOUND') coming out of my speakers (Note: After I've clicked the unmute button). However, there was no video (i.e. the complete opposite). Also if I then choose another resolution from the stream list, the original scenario reverts ('No Sound, Shows Video'). (Note: At this point, the 'mute/un-mute' button is fixed on mute, and cannot be triggered.)

Just to further my test, I then used another video which I had been using on my 1st PC, BUT starts of with the original issue of 'Shows Video, No Sound.') https://www.youtube.com/watch?v=BsIy2zefXY4

As per my original statement, I'm fairly certain this all has to do with the 'AutoPlay' being 'True', as all modern browsers are set to MUTE autplay videos for web compliant purposes.

Hope all this proves useful to trigger some ideas, as it's driving me potty.

thelevicole commented 3 years ago

Hi @Christof0007

I will be taking a look at this today and hopefully have some answers for you. In the meantime could you share your code as a reference?

Thanks

Christof0007 commented 3 years ago

@thelevicole Brill, thanks, appreciate your probably busy with other much more important stuff.

My project is VERY simple, until get the basics smooth running.

index.php

`

YT Video ID (JUST the CODE after the v=, e.g. https://www.youtube.com/watch?v=ahqUaxdad-8) :


<video data-yt2html5="https://www.youtube.com/watch?v=<?php echo $_POST["YTvidID"]; ?>" controls="controls" autoplay="false" muted="false">

`

YouTubeToHtml5.js

'use strict';function _typeof(a){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},_typeof(a)}function YouTubeToHtml5(){var a=0<arguments.length&&arguments[0]!==void 0?arguments[0]:{};for(var b in this.options)b in a&&(this.options[b]=a[b]);this.options.autoload&&this.load()}YouTubeToHtml5.prototype.options={selector:"video[data-yt2html5]",attribute:"data-yt2html5",formats:"*",autoload:!0},YouTubeToHtml5.prototype.hooks={filters:[],actions:[]},YouTubeToHtml5.prototype.getHooks=function(a,b){if(a in this.hooks){var c=this.hooks[a].sort(function(c,a){return c.priority-a.priority});return c.filter(function(a){return a.name===b})}return[]},YouTubeToHtml5.prototype.addAction=function(a,b){var c=2<arguments.length&&arguments[2]!==void 0?arguments[2]:10;this.hooks.actions.push({name:a,callback:b,priority:c})},YouTubeToHtml5.prototype.doAction=function(a){for(var b=this.getHooks("actions",a),c=arguments.length,d=Array(1<c?c-1:0),e=1;e<c;e++)d[e-1]=arguments[e];for(var f=0;f<b.length;f++){var g;(g=b[f]).callback.apply(g,d)}},YouTubeToHtml5.prototype.addFilter=function(a,b){var c=2<arguments.length&&arguments[2]!==void 0?arguments[2]:10;this.hooks.filters.push({name:a,callback:b,priority:c})},YouTubeToHtml5.prototype.applyFilters=function(a,b){for(var c=this.getHooks("filters",a),d=arguments.length,e=Array(2<d?d-2:0),f=2;f<d;f++)e[f-2]=arguments[f];for(var g=0;g<c.length;g++){var h;b=(h=c[g]).callback.apply(h,[b].concat(e))}return b},YouTubeToHtml5.prototype.itagMap={18:"360p",22:"720p",37:"1080p",38:"3072p",82:"360p3d",83:"480p3d",84:"720p3d",85:"1080p3d",133:"240pna",134:"360pna",135:"480pna",136:"720pna",137:"1080pna",264:"1440pna",298:"720p60",299:"1080p60na",160:"144pna",139:"48kbps",140:"128kbps",141:"256kbps"},YouTubeToHtml5.prototype.urlToId=function(a){var b=a.match(/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|(?:(?:youtube-nocookie\.com\/|youtube\.com\/)(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/)))([a-zA-Z0-9\-_]*)/);return Array.isArray(b)&&b[1]?b[1]:a},YouTubeToHtml5.prototype.fetch=function(a){return new Promise(function(b,c){var d=new XMLHttpRequest;d.open("GET",a,!0),d.onreadystatechange=function(){4===this.readyState&&(200<=this.status&&400>this.status?b(this.responseText):c(this))},d.send(),d=null})},YouTubeToHtml5.prototype.getAllowedFormats=function(){var a=[];return Array.isArray(this.options.formats)?a=this.options.formats:this.itagMap[this.options.formats]?a=[this.options.formats]:"*"===this.options.formats&&(a=Object.values(this.itagMap).sort()),a},YouTubeToHtml5.prototype.getElements=function(a){var b=null;return a&&(NodeList.prototype.isPrototypeOf(a)||HTMLCollection.prototype.isPrototypeOf(a)?b=a:"object"===_typeof(a)&&"nodeType"in a&&a.nodeType?b=[a]:b=document.querySelectorAll(this.options.selector)),b=Array.from(b||""),this.applyFilters("elements",b)},YouTubeToHtml5.prototype.youtubeDataApiEndpoint=function(a){var b=~~(33*Math.random()),c="https://images".concat(b,"-focus-opensocial.googleusercontent.com/gadgets/proxy?container=none&url=https%3A%2F%2Fwww.youtube.com%2Fget_video_info%3Fvideo_id%3D").concat(a);return this.applyFilters("api.endpoint",c,a,b)},YouTubeToHtml5.prototype.parseUriString=function(a){return a.split("&").reduce(function(a,b){var c=b.split("=").map(function(a){return decodeURIComponent(a.replace("+"," "))});return a[c[0]]=c[1],a},{})},YouTubeToHtml5.prototype.parseYoutubeMeta=function(a){var b=this,c=[],d={},e=this.parseUriString(a);return e.player_response=JSON.parse(e.player_response),e.fflags=this.parseUriString(e.fflags),e=this.applyFilters("api.response",e,a),e.hasOwnProperty("url_encoded_fmt_stream_map")?c=c.concat(e.url_encoded_fmt_stream_map.split(",").map(function(a){return b.parseUriString(a)})):e.hasOwnProperty("adaptive_fmts")?c=c.concat(e.adaptive_fmts.split(",").map(function(a){return b.parseUriString(a)})):e.player_response.streamingData&&e.player_response.streamingData.adaptiveFormats?c=c.concat(e.player_response.streamingData.adaptiveFormats):e.player_response.streamingData&&e.player_response.streamingData.formats&&(c=c.concat(e.player_response.streamingData.formats)),c.forEach(function(a){if(b.itagMap[a.itag]&&a.url){var c="unknown",e="unknown";if("mimeType"in a){var f=a.mimeType.match(/^(audio|video)(?:\/([^;]+);)?/i);f[1]&&(c=f[1]),f[2]&&(e=f[2])}d[b.itagMap[a.itag]]={url:a.url,label:a.qualityLabel||b.itagMap[a.itag],type:c,mime:e}}}),d=this.applyFilters("api.results",d,e),d},YouTubeToHtml5.prototype.load=function(){var a=this,b=this.getElements(this.options.selector);b&&b.length&&b.forEach(function(b){a.loadSingle(b)})},YouTubeToHtml5.prototype.loadSingle=function(a){var b=this,c=1<arguments.length&&arguments[1]!==void 0?arguments[1]:null,d=c||this.options.attribute;if(a.getAttribute(d)){var e=this.urlToId(a.getAttribute(d)),f=this.youtubeDataApiEndpoint(e);this.doAction("api.before",a),this.fetch(f).then(function(c){if(c){var d=b.parseYoutubeMeta(c);if(d){for(var e,f=b.getAllowedFormats(),g=null,h=null,j=0;j<f.length;j++)if(e=f[j],e in d){g=d[e],h=e;break}g=b.applyFilters("video.stream",g,a,h,d),a.src=b.applyFilters("video.source",g.url,g,a,h,d)}}})["finally"](function(c){b.doAction("api.after",a,c)})}},"object"===("undefined"==typeof module?"undefined":_typeof(module))&&"object"===_typeof(module.exports)&&(module.exports=YouTubeToHtml5);

Christof0007 commented 3 years ago

P.S. I've a fair impression, this is just a decoder issue, or more to the point, the video player not knowing the fetched streams are MP4 for example. But I'll leave it to the expert :-)

thelevicole commented 3 years ago

Hi @Christof0007 v4.0.0 has been published which should resolve your issue. Please note that this update includes breaking changes so make sure you read the release notes for info.

Some streams from YouTube have no audio channel so this might be where the issue lies. I've added a new option to the library to only select streams with audio avialable. This can be use like so:

new YouTubeToHtml5({
    withAudio: true
});

A working example of this can be found here: https://thelevicole.com/youtube-to-html5-loader/

Christof0007 commented 3 years ago

@thelevicole Hey there. Excellent Job, I applaud your efforts. Will look forward to giving your new version a go tomorrow, on jobs today. Thanks :-)

tapasdatta commented 3 years ago

Hi @Christof0007 v4.0.0 has been published which should resolve your issue. Please note that this update includes breaking changes so make sure you read the release notes for info.

Some streams from YouTube have no audio channel so this might be where the issue lies. I've added a new option to the library to only select streams with audio avialable. This can be use like so:

new YouTubeToHtml5({
    withAudio: true
});

A working example of this can be found here: https://thelevicole.com/youtube-to-html5-loader/

If I add it, the vodeo quality loses.

fpineda-dev commented 1 year ago
new YouTubeToHtml5({
    withAudio: true
});

Thanks so Much

Christof0007 commented 2 months ago

Hello Everyone.

@thelevicole Long time no speak, just dabbling all this time later, just trying to revive this project.

Unfortunately my project ALSO your demo project, nothing seems to function anywhere.

Any suggestions would be most welcome and appreciated. 🙂

Christof0007 commented 2 months ago

Using your example page:

https://thelevicole.com/youtube-to-html5-loader/#examples

Google Chrome console error:

YouTubeToHtml5.js:1 Uncaught (in promise) TypeError: t.getStreamData is not a function at o.value (YouTubeToHtml5.js:1:7025) at YouTubeToHtml5.js:1:3287 at Array.forEach () at o.value (YouTubeToHtml5.js:1:3255) at YouTubeToHtml5.js:1:6788