Youtube + Selenium ChromeDriver (Python) - How to know when a video ends?

11,889

Solution 1

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.
  }

Solution 2

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 "".

Solution 3

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
Share:
11,889

Related videos on Youtube

Pythonic
Author by

Pythonic

Python user for financial, scientific and fun applications

Updated on July 13, 2022

Comments

  • Pythonic
    Pythonic almost 2 years

    [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&amp;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)