View on GitHub

Yt6

Play back free of ads, tweak around with and download YouTube video & audio in almost any browser on both Desktop and Mobile

Yt6 -- Snarl's YouTube Video Player (bookmarklet)

Latest version: 2024-02-05-01:33

Features

On any YouTube video (watch) page, this bookmarklet will call an external player and load some extra functions, some of which can be used with YouTube's original player as well. Written in pure javascript with the aim to be as much platform-independent and backwards-compatible as possible. There is no installation, it works on-demand. Only a working internet connection is needed. The program is able to
  1. restrict on-site advertisement -- suppress endscreen cards, auto-skip or just auto-mute video ads (in case some may be interesting to you),
  2. resize, zoom, rotate and move around video picture arbitrarily,
  3. select the desired media sequence to loop -- custom loop segments become active once the starting and ending time input fields disappear,
  4. change playback rate ("speed" or tempo) from 0 up to 1600%,
  5. replace soundtrack with any external audio (or video) file across the net
    1. Works only if you select a video-only format of the youtube video, and play it back with the progressive download method,
  6. pick your favoured and supported video/audio codec and resolution for playback,
  7. grab media URLs directly from the "shorts" pages,
  8. download the video/audio content,
  9. occasionally extract video commercials as well, accessible through the alternative links,
  10. download subtitles/closed captions (CC)
      On bookmarklet line, you can edit the value of "add_subs" after the equal sign and between apostrophes (a comma separated list of ISO 639-1 languge codes, such as 'en, de, fr, es, ja'...) to add Google-Translated tracks of your choice,
  11. facilitate background play while your mobile is in sleep mode,
  12. bypass age verification -- it often doesn't work automatically on subsequent pages on the mobile UI, but you can use the user-agent disclosing button (browser name in red inside the download box) to manually request another navigation to the current page, which will reveal the age-restricted video's media sources (this trick works exclusively on mobile)
      Examples: Tunnel Vision (signatures encrypted), Cobra (signatures unencrypted)
  13. show videos in mobile view which are otherwise available only in desktop view mode
      Examples: Basic Instinct (MON) (STUDIO CANAL), The Relic - Trailer
  14. change between YouTube layouts by setting the cookie on exit
      YouTube stopped honoring the setting in July 2020 and shut down its classic layout for good early December. I wrote a userscript that partially restores it though. See the YouTube Classic layout section for details.

Keep in mind that this is not a browser extension. If anything it is an extension of the YouTube video page. Any event resulting in a browser page reload such as
    - leaving the current YT subdomain,
    - typing URLs directly to the address bar instead of following links,
    - or even just navigating between two points in your browsing history where a full page refresh has already taken place
will cause the program code to be removed from memory and you would need to reload it.

Please note:
A bookmarklet cannot update itself. You either come back here once in a while to check if there is a newer version, or the ever evolving YouTube site will eventually break it.



Setup

  1. Right click / hold your finger on the Yt6 link above, and "Copy link address".
    1. If you have no such option, the code is written in plain text below, select and copy it manually
  2. Bookmark any web page (this one for example)
  3. Edit the created bookmark's Properties / Location:
    1. delete its URL-address entirely, and paste this snippet of javascript code in its place. (Optionally, you can give it a name of your choice too.)
  4. Save the changes, if there is a Save button!

That's it, your bookmarklet is now ready to use.


Also, in many desktop browsers you can simply drag and drop the link to the Bookmarks Toolbar, or right click on it and select "Bookmark this link" -- however, some browsers may automatically replace the dragged / right-clicked link's content with a useless about:blank#blocked line. It is default precaution for any javascript code behind a link as this programming language is easy to abuse. The copy-paste method is your best choice.

CODE IN PLAIN TEXT

javascript:(function(){var v='e674cf1e2430f4784ffbe3b6d349ea93d70afc8b/yt6.js',y='youtube.com/',w=window,d=w.document,h=d.location.href,yt6=w.yt6||{},yt6d=w.yt6d||{};if(yt6d.loaded>=4)return void 0;if(h.split(y+'watch')[1]||h.split(y+'embed')[1]||h.split(y+'playlist')[1]||h.split(y+'shorts')[1]||h.split('/base.j')[1]=='s'){var id='snarls_player',e='script',q;yt6.loaded=0;function s(x){x=x||id;return d.getElementById(x)};function c(e){return d.createElement(e)};function a(q){s().appendChild(q);s().add_subs='en,hu,de';s().version='2024-02-05-01:33';yt6d.src=q.src};function r(){if(s()){var x;try{x=s().querySelector('#'+id)}catch(e){x=s().firstChild};if(x)s().removeChild(x)}};function b(){var i,j,o,x;o=['js','rawcdn.githack','js'];for(j,x,i=o.length;i;j=Math.floor(Math.random()*i),x=o[--i],o[i]=o[j],o[j]=x);if(yt6d.src==-1)o.splice(0,0,'raw.githubusercontent');q=c('div');q.id=id;if(q!=s())d.body.appendChild(q);var src='https://'+o[0]+'.com/snarly/yt6/'+v,src0='https://cdn.jsdelivr.net/gh/snarly/yt6@'+v;function oc(ox,oy,sr){return(oy!='js')?sr.replace(ox,oy):src0};q=c(e);q.id=id;q.src=(o[0]!='js')?src:src0; q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[1],src);q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[2],src);q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[3],src);q.onerror=function(){q=c(e);q.id=id;q.src=src.replace('https','http')};a(q);r();};a(q);r();};a(q);r();};try{a(q);}catch(f){a(q)};};function g(){try{deldiv()}catch(f){r()};yt6d.src=1;b()};if(!s()){b()};setTimeout(function(){var t=w.yt6;if(t)t.loaded=t.loaded||window['status'];if(!t||(t&&(!t.body||(t.loaded<3))))g()},3000);}else{void 0};})()/*2024-02-05-01:33*/


How to use

On Desktop, just click on it on your bookmarks list whenever you enter a YouTube video you want to play around with, unless you have the code already running.

On Mobile
  1. Tap the browser's address bar first (NOT the YouTube search bar!)
    1. this will select / highlight the whole address of the current YouTube video page.
      One exception is Microsoft Edge Mobile, whose developers decided recently that a single short tap should immediately get us to line editing mode instead of highlighting the whole line. We don't want to edit the address now, we want to overwrite it, so in the case of Edge you would have to hold your finger for a longer period of time over the address bar (till the system offers the option to "Select all").
  2. The browser should suggest the bookmarklet as an available option -- if these type of suggestions are allowed in the settings --
    1. once you start typing either its name ("Yt6" or whatever you named it) or the prefix "javascript:" to narrow the search down to bookmarklets only.
  3. Tapping on the correct entry shall initiate the call.

Loading time depends on your internet connection and the current traffic on the storage servers, but it should be up and running within a few seconds. If it doesn't seem to work, it may be because of installed script blocker extensions. See the Important Notes section to learn how to resolve this.

Automatic playback depends on the state of YouTube's own "Repeat / Loop Playlist" (the circular arrows) button on user-created playlists.

Use the HTML5 emblem on the control panel to switch between the native and this alternative player.

It is possible to use the bookmarklet code as a userscript with the help of add-ons like
    Greasemonkey (for Firefox),
    Tampermonkey (for Firefox, Chrome, Edge and Opera) or
    Violentmonkey (for Firefox, Chrome and Edge)
However, I would not recommend this (except for Yandex) because all it does is save you the time of one or two clicks / taps, while it may cause unnecessary network traffic in case of an error.

// ==UserScript==
// @name         Yt6 -- Snarl's YouTube Video Player (userscript)
// @namespace    yt6
// @version      2024-02-05-01:33
// @author       Snarl
// @description  Auto-Load Yt6 script as soon as possible
// @match        https://*.youtube.com/watch*
// @match        https://*.youtube.com/embed/*
// @match        http://*.youtube.com/watch*
// @match        http://*.youtube.com/embed/*
// @grant        none
// @run-at       document-end
// @icon         https://yt3.ggpht.com/-afBnHVG_R6E/AAAAAAAAAAI/AAAAAAAAAAA/LtE5kbPkZvE/s27-c-k-no-mo-rj-c0xffffff/photo.jpg
// ==/UserScript==

(function(){

  window['yt6'] = {}; window['yt6d'] = {}; window['yt6'].body = 1

  var idle_time = 2000 // wait some time before running the bookmarklet part

  var onComplete = function(){setTimeout( //javascript:(
	(function(){var v='e674cf1e2430f4784ffbe3b6d349ea93d70afc8b/yt6.js',y='youtube.com/',w=window,d=w.document,h=d.location.href,yt6=w.yt6||{},yt6d=w.yt6d||{};if(yt6d.loaded>=4)return void 0;if(h.split(y+'watch')[1]||h.split(y+'embed')[1]||h.split(y+'playlist')[1]||h.split(y+'shorts')[1]||h.split('/base.j')[1]=='s'){var id='snarls_player',e='script',q;yt6.loaded=0;function s(x){x=x||id;return d.getElementById(x)};function c(e){return d.createElement(e)};function a(q){s().appendChild(q);s().add_subs='en,hu,de';s().version='2024-02-05-01:33';yt6d.src=q.src};function r(){if(s()){var x;try{x=s().querySelector('#'+id)}catch(e){x=s().firstChild};if(x)s().removeChild(x)}};function b(){var i,j,o,x;o=['js','rawcdn.githack','js'];for(j,x,i=o.length;i;j=Math.floor(Math.random()*i),x=o[--i],o[i]=o[j],o[j]=x);if(yt6d.src==-1)o.splice(0,0,'raw.githubusercontent');q=c('div');q.id=id;if(q!=s())d.body.appendChild(q);var src='https://'+o[0]+'.com/snarly/yt6/'+v,src0='https://cdn.jsdelivr.net/gh/snarly/yt6@'+v;function oc(ox,oy,sr){return(oy!='js')?sr.replace(ox,oy):src0};q=c(e);q.id=id;q.src=(o[0]!='js')?src:src0; q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[1],src);q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[2],src);q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[3],src);q.onerror=function(){q=c(e);q.id=id;q.src=src.replace('https','http')};a(q);r();};a(q);r();};a(q);r();};try{a(q);}catch(f){a(q)};};function g(){try{deldiv()}catch(f){r()};yt6d.src=1;b()};if(!s()){b()};setTimeout(function(){var t=w.yt6;if(t)t.loaded=t.loaded||window['status'];if(!t||(t&&(!t.body||(t.loaded<3))))g()},3000);}else{void 0};}
    //)()/*2024-02-05-01:33*/
  , idle_time)
  }

  var check = function(){ // conditions to meet before loading
    var x = window['performance'];
    if (x && x.timing && x.timing.loadEventEnd > 0 && x.timing.loadEventEnd >= x.timing.domComplete) return true
  }

  if (check()) {
      onComplete()
      return
  }

  var delay = 500, timeout = 8000

  var timeoutPointer
  var intervalPointer = setInterval(function () {
      if (!check()) return

      clearInterval(intervalPointer)
      if (timeoutPointer) clearTimeout(timeoutPointer)
      if (typeof onComplete == 'function') onComplete()
  },delay)

  if (timeout) timeoutPointer=setTimeout(function () {
      clearInterval(intervalPointer)
  },timeout)

})()

Note:
    These "monkey"-scripts only seem to work on normal, non-incognito tabs on mobile.

    If the launched program appears dysfunctional in Desktop view mode, edit the userscript code through the manager's Dashboard* and try to set the idle_time variable to a higher value (the number is in milliseconds).
*The dashboard's editor may be useless im mobile view, switch over to desktop view mode for the time of the edit.


Background play on Mobile

You won't have to request YouTube's resource-hungry Desktop mode to be able to listen to videos over a locked screen -- the site's lightweight Mobile version will do just fine.

I recommend to use the 48k Opus audio-only format for playback to save as much bandwidth as possible. (The drop in sound quality becomes noticeable only over high-end headphones or on loud sound recordings.) Picking a video format for background play is pretty much pointless anyway and would also raise the chance of playback failure significantly.

Early 2023, YouTube chenged the behavior of its player on backgrounded tabs. Whenever your device is either locked, the browser isn't the app in the foreground, or the player's tab simply is not the active one, and navigation occurs in the background, access to new media sources will be restricted to a couple of formats only -- the ones currently loaded by the original YT player and possibly maybe one or two old-fashioned AV-formats which were kept for compatibility reasons.
And even these scarce sources may point to an advertisement, because the ad-filtering is never quite 100%: In order to get the missing formats, you will need to navigate away to a different video, and come back while the player's webpage stays in the foreground.

Now that YouTube have upgraded to the newest version of its mobile UI, there is hope that maybe three years from now its bugs will be fixed too. Playlists are simplified to the point where no native skip forward or backward buttons exist, and the list itself appears to be floating over all the other elements on the page -- stupidly covering even the player itself, most notably on Kiwi and Ecosia.

The only way I found around this was to lower the playlist object's opacity a little bit. On one hand, this makes the control panel re-appear on top of the list, but on the other hand, also reduces the size of the area by which you can grab the list in order to scroll up or down. If you still can't see the control panel (Kiwi, Ecosia), there is a backup of the panel located at the lower end of the download box, use that as a last resort. You can also manually toggle between the opacity values of 1 (default) and 0.99 by either tapping on the "Used for playback" or the "Alternatives" button.

Another important change: programmatically we can only move to the next entry of a playlist if the playlist object is not minimized and the upcoming entry is located in close proximity of the visible part of the list (i.e. it was already loaded). Every time we "close" the playlist object, the stored links to other videos become invalid in the sense that using them would trigger a full page refresh along the way, thereby removing the Yt6 script from memory. Therefore the program first attempts to automatically open the playlist object when a video is getting within 10 seconds away from the end, then tries to scroll to the current video on the list to meet these prerequisites in time before the video ends, and if they are not met, avoids attempting navigation. For now, this mechanism is in the test phase and only works if the "Remove ads" radio button is ticked.

(It is also worth noting that by mid-2023, Google finally managed to incorporate the code to auto-scroll to the mobile playlist's current video... Bravo! Although they did it at the expense of trashing the skip forward and backward buttons, which in turn was a moronic move.)


Supported browsers

On Desktop, the script should work with almost any browser now. The only criteria is that they must support the usage of bookmarklets or have userscript add-on capabilities, which most of them do.

Below is a ranking of popular Mobile browsers based on how well they work under the following conditions
    - using the script's alternative player
    - on YouTube's mobile interface (m.youtube.com)
    - while the device is in actual sleep mode (screen turned off and with no connection to any external power source through cable)

    Good ones (for Android)
  1. Firefox
    (last Desktop-based build was 68.11.0)
    slow but reliable when "hardened": the uBlock Origin add-on helps getting rid of video commercials (even if it was causing severe problems with backgrounded play recently due to an intentional compatibility break by YouTube, which was fixed around Oct 26)
  2. Mull*
    Firefox-based, strong protection against web tracking and video ads, sluggish execution
  3. Firefox Nightly
    faster than the regular firefox version and was in recent times the best option to use the script with without the problematic uBlock Origin, just make sure to turn the Search bookmarks switch on in Settings / Search / Search Bar - Firefox suggest to allow the use of bookmarklets, because it is turned off by default
    So-so (playback may fail after a few videos)
  4. Brave
    quickest native ad-filtering, was as badly affected by the recent YouTube countermeasure against ad-blocking mechanisms as Firefox was, but the issue was resolved in just like two weeks or so -- still, background play with the script usually runs out of steam after 3 or 4 videos
  5. Edge
    better than zero resistance to ads, one of the fastest browsers, background play however is testing your patience
  6. Vivaldi
    slower native ad-filtering (at least on mobile)
  7. Kiwi
    no protection against video ads, relatively slow, impaired by the recent surge of YT commercials
  8. Google Chrome
    can be excellent when the marketing calms down and useless at the time of overload
  9. Chromium*
    vanilla version of the Chromium-base, the mobile version available is fairly outdated now
  10. Ecosia
    similar to Brave, except dead slow in comparison while in the background
    Bad ones (playback works, just not in sleep mode)
  11. DuckDuckGo
  12. Yandex
    bookmarklet support was removed, now Yandex can only launch the code through a userscript manager
  13. Bromite*
    very secure Chromium variant which apparently does not allow continuous background play at all
    Unsupported
  14. Opera
    the mobile version no longer supports bookmarklets -- one less reason to use it
  15. Firefox Focus, Samsung, Qwant, Mint ...

With other conditions set -- such as turning the sleep function off -- the ranking would look much different.

*Browsers available through F-Droid, an alternative app store for Android. The website has a client app (APK download link) that, when installed on your mobile, will let you browse, install and update other apps from their repository, which by the way is more carefully inspected for malicious content than the Google Play Store. The Chromium-based browsers' install page can not be seen from the web -- because parts of that code is proprietary, thus not entirely open source -- but can be accessed via the client app. Make sure to check for an update of the F-Droid client itself before you'd attempt to update anything else, because accomplishing the latter may depend on the former.

Brave and Vivaldi both support background play on the Mobile UI natively. However, the YT player (without Premium access) will let you play only a few (typically 6-7) videos in a row, after that it will throw an alert box in your face to force some user interaction before playback could continue. The alternative player remains unaffected by this only if you use a Firefox-based browser as all of the Chromium-family bows to Google's will now.

Regardless of platform, the default "noname" browsers that come pre-installed on various systems typically have no support for bookmarklets.


Legacy browsers

Till June/July of 2020 the bookmarklet was usable with really old browsers too that were dated back to around the IE7/8 era (with the help of the Adobe Flash plugin), but now that YouTube enforces its bug-filled new layout, they broke compatibility with them.

Still, I found a way to make use of this script with outdated browsers anyway.
It's obviously discouraged to use them because of the myriad of security holes that can be found in such old sowftware, not to mention that the development of Adobe Flash also ended officially in 2020. It is possible to reactivate Flash, although only Firefox 84, Edge 87, Chrome 87 and older browsers will acknowledge the presence of the plugin now. But in case you have no other option, the possibility is there.

The trick is to visit the "embed" page which contains a stripped-down code normally used to create an embedded video on other websites. There is literally nothing on these pages beside the player itself, therefore it's super lightweight which makes it a legit choice even for modern browsers (if you just want to listen to a playlist in the background). It's clunky and inconvenient to use on mobile, not recommended there. On desktop, it's okay.

Regular video URL with playlist
https://www.youtube.com/
watch?v=
d020hcWA_Wg
&
list=PLNxOe-buLm6cz8UQ-hyG1nm3RTNBUBv3K&index=214


The "embed" variant to enter on the address bar
https://www.youtube.com/
embed/
d020hcWA_Wg
?
list=PLNxOe-buLm6cz8UQ-hyG1nm3RTNBUBv3K&index=214


Pro: the alternative player can play videos which are otherwise blocked from view in embedded frames.
Con: due to a YT limitation you can only navigate through the first 200 videos on an embedded playlist.

    The example above is the 214th entry and it will load fine as long as you use the alternative player. Just do not let the native one load because from its perspective, the current index does not exist (being outside of the boundary), hence would trigger an automatic jump to the first video, with no way to go above the 200th entry again.


Classic YouTube layout

The html code of the old layout is no longer being produced by YouTube's php servers (the javascript and css belonging to it are still accessible). That means we will only ever see the classic layout again if we produce that html ourselves.

Based on a few backup copies of YouTube page sources, I wrote a userscript which attempts to recreate the old html structures and inject them into the current page to make the two layouts co-exist at the same time.

    Note: I'm not going to update this info page every time I update the script. The above link will take you directly to the plain text userscript file -- which, by the way, does absolutely nothing until you feed its text to a suitable browser extension (preferably Tampermonkey). The version number in its header is the date of the last edit. Update your copy if it is older than that.

Unfortunately, most of the server functionality related to the old stuff were shut down, so there is a dependency on the new layout, which makes the homemade html more like a skin than a standalone interface. It still has a few advantages over the material design, such as the exact number of likes and video views, or its well-defined frames.

Sadly I never made any backup copy of the html source code while being logged in to the site. Those pages obviously looked and worked differently than the ones shown to anonymous visitors. Searching the web for such html content left me with very limited results. So don't be surprised if not everything feels exactly the way it used to.

Most bugs are attributed to the fact that the two layouts use different methods to deal with browser navigation. One notable bug occurs on old-style playlists: the player keeps jumping back to the video entry next to the one we started off from each time a third video is about to come up. This bug can be eliminated partially by clicking the playlist's "Shuffle" button (crossed arrows). The shuffle can be turned off right after it's been activated (it would not have its intended effect on the player anyway), and even though the displayed old html content may belong to a different video, at least the playback will work fine from then on.

It can be used independently from the main project script, however I advise you not to use this one on Mobile. Kiwi and Yandex would let you install browser extensions capable of running userscripts like this, but the two desktop layouts working concurrently just drains the battery too fast. It's not worth it.

Heads-up: This additional userscript was broken by YouTube / up-to-date browsers around mid-2021 and needs heavy rewriting.


Stream capturing

The yt6 script can expose URLs in the sourcechooser / download box which doesn't seem to work -- there is no way to load them for playback, and trying to download the linked content would either result in a zero-length file or merely a short segment of a live stream.

That's because there is no contiguous media file behind those links. Only fragments of media -- hardly usable in the old-fashioned way -- meant to be streamed by a player capable of streaming. You can recognize these URLs as video- or audio-only sources which have no file size displayed next to them. Since a recent update of the yt6 code, along with the stream URLs appears a link to a "DASH Manifest", and in case of live streams, a "HLS Manifest" too, which are XML documents containing info on the streamable bits.

Here is one example of the "yt_otf" type.
    (YouTube may replace the stream-only URLs with regular ones after the video reaches a certain level of popularity.)
And here is the "yt_live_broadcast" type.

I wrote a small bash shell script called yt_streamcat which makes it possible to save the media behind those type of URLs as well. It's a Command Line Interface (CLI) utility which relies on a widely used binary program called wget to be installed on the system. Having ffmpeg, "The swiss army knife of Internet Streaming" installed is a huge bonus, and in case ffmpeg produces broken media, you may need an alternative tool capable of media muxing, such as mencoder, to process the broken file and fix it for good.

The script is supplementary code to do the job which is not possible for the yt6 main program in a javascript environment. Save the program file (link below) to an accessible subfolder on your computer -- preferably a dedicated folder you don't mind getting filled up with temporary media file segments -- open a virtual terminal with the bash shell running and change working directory ("cd" in)to that folder.

Currently, the script has only a Linux version available, but it shouldn't be too hard to port it to Windows.

Under Linux, newly created or downloaded files cannot be run by default, regardless of whether they are meant to be executables or not. Technically speaking they are not marked as executable, for security reasons. In order to make a file executable for your own user only, you must run the following command at the shell prompt:
chmod u+x [path to file/]filename

The script command itself must be issued the following way:
./yt_streamcat target_file "stream_base_URL" start end "2nd_stream_URL"

where
    ./ means the program file is located in the current directory (in Windows, .\ would mean the same thing)
    yt_streamcat
      is the script file we run as our command
    target_file (mandatory)
      is a user-specified file the media segments are going to be written into -- must not exist yet, if it does, the script will abort to prevent an accidental overwrite
    "stream_base_URL" (mandatory)
      is a YT stream source URL originating from one of the two possible types of videos mentioned above, extracted by the yt6 main program. Must be enclosed in quotation marks to prevent bash from misinterpreting each URL-parameter (after each "&" sign) as yet another command to run in the background.
    start (optional)
      is the number of the segment the media should begin download from. For live streams, you should give this a value somewhere between the first and last available "sq" (segment query?) parameter values which you can read on the DASH and HLS Manifest URL lines. If you go over that range, the download will start with the most recent live segment. If you go below it, the download will stall.
    end (optional)
      is the number of the ending segment, or if it's less than the previous number, it will be interpreted as the number of segments to download
    "2nd_stream_URL" (optional)
      to save another track parallel to the first one (an audio stream, maybe?). Must be between quotes as well. (You must specify the previous two options in order to be able to specify this fifth one.)

It is easier to write a wrapper script to handle the program rather than always have to type out the whole command line yourself. Then just edit the part which needs to be changed. The wrapper should look like something like this:
#!/bin/bash

./yt_streamcat v \
"https://[...]googlevideo.com/videoplayback?[...]" \
100 \
150 \
"https://[...]googlevideo.com/videoplayback?[...]"
	

where the target file will be "v" (thus the secondary source will be saved to "vA"), number 100 is going to be the first segment to be saved and 150 will be the last. Notice the \ character, which is the escape character in most programming languages. It escapes a line break inside the wrapper for the lines before and after it which bash is supposed to interpret as a single line of command. (No other character must be present between the escape character and the following invisible newline character.) You can name the wrapper file anything you want, just make it executable the same way as above, then enter ./[wrapper_filename], and it will run the command(s) inside of it.

One way to abort a running bash script process is to hit Ctrl+C on the terminal. A temporary helper script is always generated automatically for such events to take care of the remaining minimum steps in the muxing procedure. Its default filename is 0[target_filename]-yt_streamcat-ffmpeg, you just have to execute it.

In my tests, live-streamed webm video content seemingly encoded as 30fps, had to be regularly remuxed to a framerate of anywhere between 36 and 36.25fps in the saved file, then also remove one segment from the beginning in order to get it synced up with the audio track. No idea why that is the case, but it is. For higher framerates, the difference should be even larger.

Remuxing commandline examples:
To fix a broken mp4
mencoder v.mp4 -ovc copy -o v2.mp4
To change the framerate of a webm from 30 to 36
mencoder v.webm -ovc copy -mc 0 -noskip -fps 30 -ofps 36 -o v2.webm
To cut the first video segment out, mencoder's seek option must be a bit less than each segment's duration, so if they are 5 seconds long, 4 seconds will do
mencoder v2.webm -ovc copy -ss 4 -o v3.webm
Finally, to mux the video and audio into one matroska file
ffmpeg -i v3.webm -i vA.aac -c:v copy -c:a copy v.mkv
Check if the mkv is playable, then remove the intermediate files.

__


Credit should go to the authors of their respective open source code I had my own built around:

John Dyer - Mediaelementplayer - http://mediaelementjs.com/
Christian Heilmann - Transformvideo - http://github.com/codepo8/rotatezoomHTML5video
Steven Penny - Youtube download bookmarklet - (closed account)


This program is free to use for anyone.

__


Important Notes


  1. If you use add-ons like NoScript (a recommended practice), make sure to

    Whitelist / Trust these domains permanently:
    githubusercontent.com - program code is stored on this site
    jsdelivr.net - #1 cdn proxy to load the files
    githack.com - #2 (does not always fix the Content-Type header...)
    rawgit.com - #3 (now redirects to jsdelivr's cdn)
    api.codetabs.com - (should not be necessary but it wouldn't hurt either)
    youtube.com - won't even budge without its own javascript code running
    googlevideo.com - youtube media is delivered through this domain

  2. On videos with strong copyright protection, it is often the case that YouTube sends deliberately wrong signature decryption keys on the first try. I did not implement a fully automatic update of video signatures because of the high risk of infinite loop on repeated failure. You MUST switch over to the alternative player to initiate playback on multiple formats manually till enough errors occur for the updating procedure to fire. The video can be downloaded as soon as it becomes playable on the alt-player. The appearing blue gauge on its time rail shows that the video data has arrived and is buffering.


  3. The alternative player of Yt6 uses the Progressive Download method to access video & audio instead of the Adaptive Streaming YouTube's own player had as the default since late 2013.

    Both have their pros and cons. With the former, media is getting piled up in the browser's cache during playback, which means there must be enough free space for storage either in the system RAM or on the disk. While in the case of streaming, you only have tiny slices of the media buffered at all times, which in turn requires higher CPU-power and constantly fast network speeds.
    Consequently, for live streams or Ultra-HD videos it is recommended to switch over to YouTube's native player, as it is much better suited for those.

    To make sure your browser chooses memory over the much slower and/or fragile Hard Disk / Solid-state drive, use the program in an Incognito / In-private browser window or tab.


  4. Occasionally, some age-restricted videos may get the same subdomain for their source location as known YouTube video commercials which have already been registered with adblockers such as uBlock Origin or Brave Browser's ad-shield, and as a result, their download links will be made inaccessible by these adblockers as well. Except if

    1. you are logged in to an eligible YouTube account
    2. don't use ad-blockers at all
    3. or set up exceptions in the ad-blocker's settings

    For example, on uBlock Origin's control panel, the explicit greenlighting of the domains

    youtube.com -- for the player data and
    googlevideo.com -- to access the media links

    will do the trick, although this way you may end up getting some video ads too.
    (You first need to activate the Advanced User mode in uBlock Origin's settings menu to be able to do this. Tutorial: https://www.youtube.com/watch?v=SIYcI2tEqo8)


  5. Attention!

      Since late May 2022, many up-to-date Chromium-based browsers started to show a warning message when you tried to load the script. The message states that your device was about to connect to a site known for malicious activities, hence loading was aborted. The domain name highlighted in the message is an alias for a well-known site providing free tools for basic internet traffic analytics

      I have been using a logger from this 3rd party site as the only free solution to see how frequently the program was being used, without having to run a server machine 24/7 myself just to call back to. I do not care about IPs or locations and have wiped the logs clear on a regular basis. But unfortunately there are enough indecent people with bad intentions to get the service's domain names blacklisted.

      To prove that my own code has nothing to do with what Google's security warning would suggest, I present a barely modified version of the one from April 29, which won't trigger any warning. The difference is only 4 characters, by which I commented a single line out (line number 14175), thereby preventing the attempt to load the 3rd party stuff (a 1x1 pixel image). So, this way we got rid of the tracker, I know nothing about usage stats and Google security does not complain.

      Modified version, free of this particular issue:
      Test bookmarklet:
      javascript:(function(){var v='91be8ce0c40728565342b83e888cdd0b1ba760a7/yt6.js',y='youtube.com/',w=window,d=w.document,h=d.location.href,yt6=w.yt6||{},yt6d=w.yt6d||{};if(yt6d.loaded>=4)return void 0;if(h.split(y+'watch')[1]||h.split(y+'shorts')[1]||h.split(y+'embed')[1]||h.split('/base.j')[1]=='s'){var id='snarls_player',e='script',q;yt6.loaded=0;function s(x){x=x||id;return d.getElementById(x)};function c(e){return d.createElement(e)};function a(q){s().appendChild(q);s().add_subs='en,hu,de';yt6d.src=q.src};function r(){if(s()){var x;try{x=s().querySelector('#'+id)}catch(e){x=s().firstChild};if(x)s().removeChild(x)}};function b(){var i,j,o,x;o=['js','rawcdn.githack','cdn.rawgit','js'];for(j,x,i=o.length;i;j=Math.floor(Math.random()*i),x=o[--i],o[i]=o[j],o[j]=x);if(yt6d.src==-1)o.splice(0,0,'raw.githubusercontent');q=c('div');q.id=id;if(q!=s())d.body.appendChild(q);var src='https://'+o[0]+'.com/snarly/yt6/'+v,src0='https://cdn.jsdelivr.net/gh/snarly/yt6@'+v;function oc(ox,oy,sr){return(oy!='js')?sr.replace(ox,oy):src0};q=c(e);q.id=id;q.src=(o[0]!='js')?src:src0;q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[1],src);q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[2],src);q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[3],src);q.onerror=function(){q=c(e);q.id=id;q.src=src.replace('https','http')};a(q);r();};a(q);r();};a(q);r();};try{a(q);}catch(f){a(q)};};function g(){try{deldiv()}catch(f){r()};yt6d.src=1;b()};if(!s()){b()};setTimeout(function(){var t=w.yt6;if(t)t.loaded=t.loaded||window['status'];if(!t||(t&&(!t.body||(t.loaded<3))))g()},3000);}else{void 0};})()/*2022-04-29-1900-alt*/

      The original, which Google started screaming about.
      Yt6 file: /*2022-04-29-1900*/ (just for comparison)
      Test bookmarklet:
      javascript:(function(){var v='061efac41f9a75bc2b33fbf479de05fb5121ebcf/yt6.js',y='youtube.com/',w=window,d=w.document,h=d.location.href,yt6=w.yt6||{},yt6d=w.yt6d||{};if(yt6d.loaded>=4)return void 0;if(h.split(y+'watch')[1]||h.split(y+'shorts')[1]||h.split(y+'embed')[1]||h.split('/base.j')[1]=='s'){var id='snarls_player',e='script',q;yt6.loaded=0;function s(x){x=x||id;return d.getElementById(x)};function c(e){return d.createElement(e)};function a(q){s().appendChild(q);s().add_subs='en,hu,de';yt6d.src=q.src};function r(){if(s()){var x;try{x=s().querySelector('#'+id)}catch(e){x=s().firstChild};if(x)s().removeChild(x)}};function b(){var i,j,o,x;o=['js','rawcdn.githack','cdn.rawgit','js'];for(j,x,i=o.length;i;j=Math.floor(Math.random()*i),x=o[--i],o[i]=o[j],o[j]=x);if(yt6d.src==-1)o.splice(0,0,'raw.githubusercontent');q=c('div');q.id=id;if(q!=s())d.body.appendChild(q);var src='https://'+o[0]+'.com/snarly/yt6/'+v,src0='https://cdn.jsdelivr.net/gh/snarly/yt6@'+v;function oc(ox,oy,sr){return(oy!='js')?sr.replace(ox,oy):src0};q=c(e);q.id=id;q.src=(o[0]!='js')?src:src0;q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[1],src);q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[2],src);q.onerror=function(){q=c(e);q.id=id;q.src=oc(o[0],o[3],src);q.onerror=function(){q=c(e);q.id=id;q.src=src.replace('https','http')};a(q);r();};a(q);r();};a(q);r();};try{a(q);}catch(f){a(q)};};function g(){try{deldiv()}catch(f){r()};yt6d.src=1;b()};if(!s()){b()};setTimeout(function(){var t=w.yt6;if(t)t.loaded=t.loaded||window['status'];if(!t||(t&&(!t.body||(t.loaded<3))))g()},3000);}else{void 0};})()/*2022-04-29-1900*/


      If something like this were to happen again in the future, at least you know what's going on. Hopefully I will find a better solution by then.