[Edit: solved, see mid-way in text of question]
Quick question on understanding the contents of a Youtube page with a video playing in it:
In summary
I use Selenium to play videos on Youtube, as part of a browser-based GUI.
I need to know when the video has finished playing, for the GUI to do something else (e.g. feed local HTML into the browser).
Code snippet and question
import os, time
from selenium import webdriver
# [...]
chromedriver = 'path_to_chromedriver_binary' # substitute as appropriate
driver = webdriver.Chrome(chromedriver)
youtube_link = 'https://www.youtube.com/watch?v=somevideo'
driver.get(youtube_link)
At this point, I could time.wait()
for the length of the video.
However, I wonder if I could query the YouTube page via the Selenium driver and gauge the time remaining for the play-through in a while loop (I am not familiar with how to extract this info from a youtube page)
Thanks!
[Edits with solution]
Selenium Solution
Thanks to Stanjer, and to this answer and this other answer, you can get the movie_player
status through this method:
player_status = driver.execute_script("return document.getElementById('movie_player').getPlayerState()")
(don't forget to add "return" at the beginning of the script)
Selenium Alternative Solution
Less elegant but worth pointing out:
driver.text
returns a string representing the video timer in this string format '1:00 / 2:00'. Therefore you can check if the video has played through by something along these lines:
video_is_playing = True
while video_is_playing:
time.sleep(1)
video_is_playing = not(driver.text[:4] == driver.text[-4:])
[edit] As per Jose's comment, this info can also be accessed by:
driver.find_element_by_class_name("ytp-time-current").text
Complication and next question
I need to open up the video in maximised format, and with autoplay.
This means I call the following url:
youtube.com/v/<video_code>?rel=0&autoplay=1
However this returns a very short html which only contains an embed code, as per example here:
<HTML><HEAD></HEAD>
<BODY leftMargin=0 scroll=no topMargin=0>
<EMBED height="100%"
type=application/x-shockwave-flash
width="100%"
src=https://www.youtube.com/v/Fsc-oT9PsSQ?rel=0&autoplay=1
fullscreen="yes">
</BODY>
</HTML>
So I have no movie_player
element here.
Approach 1 - can I extract the timer from the application/x-shockwave-flash
?
Approach 2 - If I launch the youtube video in a classic Youtube page, how can I tell the movie_player
to maximise itself?
(note: this answer and this answer probably contain info to solve approach 2, will post if I get this to work with Selenium)
You can execute javascript API in context of youtube video page:
youtubePlayer = document.getElementById("movie_player");
youtubePlayer.getPlayerState();
So according to https://developers.google.com/youtube/js_api_reference?csw=1
state == 0
is when a video has ended
You can add an executor in a loop checking the state every N seconds.
You can also use the 'onStateChange' function of the Youtube iFrame API to print whenever the state changes.
function onPlayerStateChange(event) {
console.log(player.getPlayerState()); // 1 = Playing || 2 = Paused || 3 = <<- O ->> || 0 = Finished.
}
You can get the length of video and current playing time as text and then convert them into seconds. Also, as a loop you can wait until the current time reaches the length of the video.
length_str = driver.find_element_by_class_name("ytp-time-duration").text
current_time_str = driver.find_element_by_class_name("ytp-time-current").text
import re
length = re.findall(r'\d+', length_str) # convert ['2:24'] to ['2', '24']
current_time = re.findall(r'\d+', current_time_str)
length_sec = 60 * int(length[0]) + int(length[1])
current_time_sec = (60 * int(current_time[0]) + int(current_time[1]))
remaining_time = length_sec - current_time_sec
driver.find_element_by_class_name("ytp-time-current").text
it only works while the time and title are shown on the screen. Once a couple of seconds past, the titles disappears and the returned value is "".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With