mirror of
				https://github.com/iv-org/invidious.git
				synced 2025-10-31 04:32:02 +00:00 
			
		
		
		
	Add playlist support to embedded videos
This commit is contained in:
		| @@ -468,6 +468,13 @@ end | ||||
| get "/embed/:id" do |env| | ||||
|   locale = LOCALES[env.get("preferences").as(Preferences).locale]? | ||||
|   id = env.params.url["id"] | ||||
|   plid = env.params.query["list"]? | ||||
|  | ||||
|   if md = env.params.query["playlist"]? | ||||
|        .try &.match(/[a-zA-Z0-9_-]{11}(,[a-zA-Z0-9_-]{11})*/) | ||||
|     video_series = md[0].split(",") | ||||
|     env.params.query.delete("playlist") | ||||
|   end | ||||
|  | ||||
|   preferences = env.get("preferences").as(Preferences) | ||||
|  | ||||
| @@ -483,7 +490,33 @@ get "/embed/:id" do |env| | ||||
|     next env.redirect url | ||||
|   end | ||||
|  | ||||
|   if id.size > 11 | ||||
|   # YouTube embed supports `videoseries` with either `list=PLID` | ||||
|   # or `playlist=VIDEO_ID,VIDEO_ID` | ||||
|   if id == "videoseries" | ||||
|     url = "" | ||||
|  | ||||
|     if plid | ||||
|       begin | ||||
|         videos = fetch_playlist_videos(plid, 1, 1, locale: locale) | ||||
|       rescue ex | ||||
|         error_message = ex.message | ||||
|         next templated "error" | ||||
|       end | ||||
|  | ||||
|       url = "/embed/#{videos[0].id}" | ||||
|     elsif video_series | ||||
|       url = "/embed/#{video_series.shift}" | ||||
|       env.params.query["playlist"] = video_series.join(",") | ||||
|     else | ||||
|       next env.redirect "/" | ||||
|     end | ||||
|  | ||||
|     if env.params.query.size > 0 | ||||
|       url += "?#{env.params.query}" | ||||
|     end | ||||
|  | ||||
|     next env.redirect url | ||||
|   elsif id.size > 11 | ||||
|     url = "/embed/#{id[0, 11]}" | ||||
|  | ||||
|     if env.params.query.size > 0 | ||||
|   | ||||
| @@ -23,6 +23,80 @@ | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|   <%= rendered "components/player" %> | ||||
| <%= rendered "components/player" %> | ||||
|  | ||||
| <script> | ||||
| <% if plid %> | ||||
| function get_playlist(timeouts = 0) { | ||||
|     if (timeouts > 10) { | ||||
|         console.log("Failed to pull playlist"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     var plid = "<%= plid %>" | ||||
|  | ||||
|     if (plid.startsWith("RD")) { | ||||
|         var plid_url = "/api/v1/mixes/<%= plid %>?continuation=<%= video.id %>&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>"; | ||||
|     } else { | ||||
|         var plid_url = "/api/v1/playlists/<%= plid %>?continuation=<%= video.id %>&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>"; | ||||
|     } | ||||
|  | ||||
|     var xhr = new XMLHttpRequest(); | ||||
|     xhr.responseType = "json"; | ||||
|     xhr.timeout = 20000; | ||||
|     xhr.open("GET", plid_url, true); | ||||
|     xhr.send(); | ||||
|  | ||||
|     xhr.onreadystatechange = function() { | ||||
|         if (xhr.readyState == 4) { | ||||
|             if (xhr.status == 200) { | ||||
|                 if (xhr.response.nextVideo) { | ||||
|                     player.on('ended', function() { | ||||
|                         location.assign("/embed/" | ||||
|                             + xhr.response.nextVideo | ||||
|                             + "?list=<%= plid %>" | ||||
|                             <% if params[:listen] %> | ||||
|                             + "&listen=1" | ||||
|                             <% end %> | ||||
|                             <% if params[:autoplay] %> | ||||
|                             + "&autoplay=1" | ||||
|                             <% end %> | ||||
|                             <% if params[:speed] %> | ||||
|                             + "&speed=<%= params[:speed] %>" | ||||
|                             <% end %> | ||||
|                         ); | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     xhr.ontimeout = function() { | ||||
|         console.log("Pulling playlist timed out."); | ||||
|         get_playlist(timeouts + 1); | ||||
|     }; | ||||
| } | ||||
|  | ||||
| get_playlist(); | ||||
| <% elsif video_series %> | ||||
| player.on('ended', function() { | ||||
|   location.assign("/embed/" | ||||
|     + "<%= video_series.shift %>" | ||||
|     <% if !video_series.empty? %> | ||||
|     + "?playlist=<%= video_series.join(",") %>" | ||||
|     <% end %> | ||||
|     <% if params[:listen] %> | ||||
|     + "&listen=1" | ||||
|     <% end %> | ||||
|     <% if params[:autoplay] %> | ||||
|     + "&autoplay=1" | ||||
|     <% end %> | ||||
|     <% if params[:speed] %> | ||||
|     + "&speed=<%= params[:speed] %>" | ||||
|     <% end %> | ||||
|   ); | ||||
| }); | ||||
| <% end %> | ||||
| </script> | ||||
| </body> | ||||
| </html> | ||||
|   | ||||
| @@ -249,7 +249,6 @@ function number_with_separator(val) { | ||||
| <% sub_count_text = video.sub_count_text %> | ||||
| <%= rendered "components/subscribe_widget_script" %> | ||||
|  | ||||
|  | ||||
| <% if plid %> | ||||
| function get_playlist(timeouts = 0) { | ||||
|     playlist = document.getElementById("playlist"); | ||||
| @@ -310,8 +309,8 @@ function get_playlist(timeouts = 0) { | ||||
|     xhr.ontimeout = function() { | ||||
|         console.log("Pulling playlist timed out."); | ||||
|  | ||||
|         comments = document.getElementById("playlist"); | ||||
|         comments.innerHTML = | ||||
|         playlist = document.getElementById("playlist"); | ||||
|         playlist.innerHTML = | ||||
|             '<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3><hr>'; | ||||
|         get_playlist(timeouts + 1); | ||||
|     }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Omar Roth
					Omar Roth