Search code examples
iframeyoutubeyoutube-apiclojurescriptreagent

Can't embed certain YouTube videos, iframe displays "the video contains content from WMG. it is restricted from playback on certain sites"


I'm building an instant YouTube client in ClojureScript and Reagent, it's currently live at http://instatube.net/ when I try to play most music videos, it displays the error "the video contains content from X. it is restricted from playback on certain sites", yet the same video plays just fine on my local server, the iframe sends the same referer and origin headers in both cases, it also works when I embed the video here https://www.w3schools.com/html/tryit.asp?filename=tryhtml_default I don't understand what the issue is, this is my iframe reagent component

[:iframe {:class "embed-responsive-item"
          :allow-full-screen "allowfullscreen"
          :frame-border 0
          :auto-play 1
          :src (str "https://www.youtube.com/embed/" (if (nil? videoId) 
          "SW-BU6keEUw" videoId) "?autoplay=1&enablejsapi=1")}]]

and this is the ajax request I'm sending to the YouTube search API v3 using cljs-ajax

(fn [term]
  (ajax/GET
    "https://www.googleapis.com/youtube/v3/search"
    {:params {:q term
              :maxResults 5
              :part "snippet"
              :type "video,playlist"
              :key YOUTUBE_API_KEY}
    :handler handle-youtube-resonse
    :response-format (ajax/json-response-format {:keywords? true})
    :headers {:referer "https://www.youtube.com/"
              :x-spf-referer "https://www.youtube.com/"}))

Solution

  • Related error was also encountered in this SO post.

    Certain videos have a domain-level whitelist or blacklist applied to them. This is done at the discretion of the content owner.

    If there is a whitelist or a blacklist, and the domain of the embedding site can't be determined (perhaps because of there not being a real referring domain in the case of your native application), then the default behavior is to block playback.

    This blog post has a bit more detail as well: http://youtube-eng.blogspot.co.uk/2011/12/understanding-playback-restrictions_28.html

    Another answer also has a point, that if you are trying to request a blacklisted video from an app and not a web page, you will get the error message below:

    "This video contains content from ___. It is restricted from playback on certain sites."
    

    You are incorrectly blacklisted. Check this answer in a SO post to to fix this.

    You need to supply your Youtube API request with an origin.

    In your request header for the Youtube video, set Referer to the domain in which you intend to be making the call from, (for ex. the domain of your app's corresponding website). If you don't have a domain, you could easily write some other domain, and that might work too.

    • For Android (Java), you can see an example here.
    • For iOS, look above
    • For React Native, you can use the origin prop on the component to your domain (origin is mentioned in the docs but doesn't tell you much about it).
    • Here is another example of the same issue in a browser when an extension blocked the Referer header from being sent for good measure.

    Note:This answer works for the V3 API of Youtube.