I save youtube links in a datastore for viewing in batches according to topic.
I basically save the videoid with a caption note and the length data.
I used php to construct a custom viewer. I've been using it for at least 10 months exactly the way I want. One breaking change to the format happened during this time and I was able to adjust to that change.
Now, today, it looks like another breaking change has happened and I'm curious to see if it's my code or if it's youtube's embed syntax.
So here's a list of youtube video id's from the Veritasium channel:
2KZb2_vcNTg,Ux33-5k8cjg,vqDbMEdLiCs,myh94hpFmJY,Iuv6hY6zsd0,vWVZ6APXM4w,BD6h-wDj7bw,1Xp_imnO6WE,38gVZgE39K8,XAgXwUwQoPA,rAYW9n8i-C4
I dynamically construct an iframe with this baseline syntax:
<iframe id="myiframe" class="myplaylist" width="720" height="405" src="https://www.youtube.com/embed/videoseries?playlist= <comma separated list of video id's> &controls=1?enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>
So a functional iframe element created from these two pieces looks this:
<iframe id="myiframe" class="myplaylist" width="720" height="405" src="https://www.youtube.com/embed/videoseries?playlist=2KZb2_vcNTg,Ux33-5k8cjg,vqDbMEdLiCs,myh94hpFmJY,Iuv6hY6zsd0,vWVZ6APXM4w,BD6h-wDj7bw,1Xp_imnO6WE,38gVZgE39K8,XAgXwUwQoPA,rAYW9n8i-C4&controls=1?enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>
This won't work as a snippet, but as an html element, it should show a youtube player, and in the upper right show a counter and drop down list of the queued videos as though you were looking at a playlist on the youtube site.
For example (Except this one is demonstrating the new problem):
It would help if someone would try this completed tag, and see if the embedded player functions.
I can't tell what's gone wrong.
I think it's YouTube. I don't know whether it is intended or a bug, but something certainly changed on YouTube's end.
If you copy the URL of the video it is https://youtu.be/videoseries - YouTube no longer recognizes /videoseries as a special URL and simply tries loading it as if it were a video slug at the front of the playlist.
It looks like a potential workaround is simply removing videoseries from the embed URL, like this:
<iframe id="myiframe" class="myplaylist" width="720" height="405" src="https://www.youtube.com/embed/?playlist=2KZb2_vcNTg,Ux33-5k8cjg,vqDbMEdLiCs,myh94hpFmJY,Iuv6hY6zsd0,vWVZ6APXM4w,BD6h-wDj7bw,1Xp_imnO6WE,38gVZgE39K8,XAgXwUwQoPA,rAYW9n8i-C4&controls=1?enablejsapi=1" frameborder="0" allowfullscreen=""></iframe>
According to a client whose embedded YouTube videos broke in the same manner today, when he reviewed a playlist in his YouTube account today there is now a new URL provided for embedding it. We replaced the old URL with the new one and the problem is fixed.
New URL is of the format https://www.youtube.com/embed/<new id code>
Old URL is of the format https://www.youtube.com/embed/videoseries?list=<old id code>
Related
I would like to add YouTube embeded video with a URL that's saved with the post.
Could someone point in the right direction?
I've done some quick research and ended looking for this solution: https://gorails.com/forum/embed-youtube-video-in-rails-app
With the iFrame you just need the embeded url of the video, which would look this:
https://www.youtube.com/embed/lQOLrycmXC4
Here is an example of implementation of the iFrame in a Rails view:
<iframe src='<%= #post.youtube_url %>?enablejsapi=1&autoplay=1" frameborder="0" allowfullscreen=""></iframe>
Where youtube_url = https://www.youtube.com/embed/lQOLrycmXC4
I want to manipulate a youtube video to autoplay and loop using js/jquery. It seems my issues stem from the from the fact that my site is on a CMS (Drupal), and it already spits out the iframe. So it's not an empty div that gets replaced as per the documentation.
The first thing I did was to change some settings on my site to ensure that "enablejsapi=1" and an ID was included in the output for whatever spits out the iframe.
I thought that would suffice and I'd only need to reference that ID in the onYouTubeIframeAPIReady(); function. But it wasn't working.
I looked at these solutions as well:
Listening for Youtube Event with this http://jsfiddle.net/YzvXa/197 - It didn't quite work for me. The state change did seem to be working in the fiddle, but when I tried to add parameters it didn't. (I'm assuming parameters only work when applied on load/ready?)
Already embedded iframe not working with api with this http://jsfiddle.net/y89je0k8/ - I feel like this got me closer, as I was able to atleast autoplay and mute using event.target.playVideo().mute(); for the ready event. How ever setting parameters like controls: 0 etc didn't.
What confuses me is in the second solution, it only works when the js is "inline". In the fiddle it's actually written in the html box in a script tag, but if you move the script in the js box, it doesn't.
Still I do feel like the points stated in the second solution might point me in the right direction, but I'm stuck in how to move forward with it.
onPlayerReady will not fire the ready check on localhost.
Also when linking your youtube.js file it has to come after the iframe.
add ?enablejsapi=1
sometimes double linking in both player_api and iframe_api will also help
//< before www. not https://
placment is key.
Here's what I've tried:
I've addressed #1 by actually adding my js in the server
My script is linked just before the closing body tag (so it is after the iframe)
I have adjusted my cms' youtube handler (Media: Youtube for Drupal) to add this parameter on output
I have tried this but it didn't seem to make a difference
I am limited by this as I am bound to using https. Is this the deal breaker?
I do notice that when I add the standard code to load the the iframe api asynchronously in my js, the <script src="https://www.youtube.com/iframe_api"></script> and <script type="text/javascript" id="www-widgetapi-script" src="https://s.ytimg.com/yts/jsbin/www-widgetapi-vflC6bXIS/www-widgetapi.js" async=""></script> appears as the first items in <head>, instead of just directly after the iframe as it normally would. I'm unsure why this is happening, but what can I do to ensure it's in the correct place? Perhaps this is the source of the issue, if placement is the key?
What I want to achieve is this behaviour: https://codepen.io/cee-r/pen/PMaRJR, where the video accepts parameters set in js when the html markup is already:
<iframe id="player" title="YouTube video player" width="640" height="360" src="https://www.youtube.com/embed/ApXoWvfEYVU?enablejsapi=1" frameborder="0" allowfullscreen="1" ></iframe>
instead of:
<div id="player"></div>
Here's my problem. The website I am working on has a slew of different products that could possibly have a link to a YouTube Video or Playlist. I have been requested to embed that link on the page instead of sending the end-user away from the page to view the video/playlist. Easy enough.
I'm using a JSTL fn.substring and fn.substringAfter to isolate the VideoID and PlaylistID of each URL that is imported into the page
<c:if test="${hyperlink.type.name eq 'YouTubeLinking'}">
<c:set var="videoSub" value="${fn:substringAfter(hyperlink.link, 'watch?v=')}"/>
<c:set var="videoID" value="${fn:substring(videoSub, 0, 11)}"/>
<c:set var="playlistSub" value="${fn:substringAfter(hyperlink.link, 'list=')}"/>
<c:set var="playlistID" value="${fn:substring(playlistSub, 0, 34)}"/>
I am then using a simple IF conditional to look at the PlaylistID, and if it its empty, then just employ the single video embed.
<c:if test="${empty playlistID}">
<iframe width="540" height="304" src="https://www.youtube.com/embed/<c:out value="${videoID}"/>?rel=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</c:if>
<c:if test="${not empty playlistID}">
<iframe width="540" height="304" src="https://www.youtube.com/embed/videoseries?list=<c:out value="${playlistID}"/>" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</c:if>
The problem is... A lot of these Playlists are no longer valid, meaning the playlist has been deleted. We're talking thousands of products that could potentially link to hundreds of playlists.
Is there anyway that I can use the YouTube API to check to see if the PlayListID is valid (will not return a 400 error), and if it is not valid, then just employ the single video embed markup?
I'm the author of Video Link Checker plugin. Here is what I recommend you do:
1) Make an API call for playlistItems with the playlist ID.
2) If the API returns an empty result, the playlist has been deleted. Otherwise,
3) Has the playlist->status->privacyStatus been changed and no longer public? (not uncommon)
4) Is the playlist->contentDetails->itemCount > 0? Sometimes the playlist owner removes all the videos but leaves the playlist active.
5) Are there playlist->contentDetails->regionRestrictions? Check vs target region to see if the embedded video will even play.
Call Youtube Data API's Playlists: list which returns all of a channel's playlist. Pass snippet as part parameter as it returns info like title and id. Compare the response to what you have. That way you'll know if a Playlist still exists.
YouTube recently discarded the old "embed" code and replaced it with iframe code.
In the new iframe code I found the way to loop+autostart videos on my website, thanks to this article. It says:
It's important to note that the “loop” parameter needs to work together
with the “playlist” parameter. This means that we are looping a
playlist that has only one video. So the embed code will look like
this:
<iframe width=”560″ height=”315″ src=”http://www.youtube.com/embed/V3oJR5IAMxM?rel=0&autoplay=1&loop=1&playlist=V3oJR5IAMxM” frameborder=”0″ allowfullscreen></iframe>
But in my new code, why does each plalist have the two same videos?
When I apply the code the playlist, it has the same two videos in it. See for example:
How can I have only one video per playlist? I never created any playlists. YouTube shows by default that I have the same 2 videos in a playlist.
This is the correct way to loop the videos of a playlist (as Google explains here)
<iframe width="100%" height="100%" src="http://www.youtube.com/embed?
listType=playlist&
list=PLAYLIST_ID&
version=3&
loop=1&
autoplay=1&
rel=0&
showinfo=0&
controls=0&
autohide=1
" frameborder="0" allowfullscreen></iframe>
I came here with a similar question. That question has been solved, heres how i did it.
Where you link the source, just get the original embed code, then replace the part that says embed with v.
ex:
www.youtube.com/v/lG5aSZBAuPs
(embed was originally here, now its a v)
Now add these attributes (or whatever the name for them would be) to the end of that embed link:
&autoplay=1
&loop=1
&playlist=lG5aSZBAuPs <-- this is the video id shown at the end of the embed source link.
so at the end the link should look like so:
<iframe width="853" height="480" src="//www.youtube.com/v/lG5aSZBAuPs&autoplay=1&loop=1&playlist=lG5aSZBAuPs" frameborder="0" allowfullscreen></iframe>
Copy the YouTube Embedded code then make these amendments.
Change embed to v
insert &autoplay=1
insert &loop =1
insert &playlist = "video-id"
This gives:
<iframe width="420" height="315" src="//www.youtube.com/v/agAX34aHvCM&autoplay=1&loop=1&playlist=agAX34aHvCM" frameborder="0" allowfullscreen></iframe>
There are so many people having trouble with this.....
Note: This parameter has limited support in the AS3 player and in IFrame embeds, which could load either the AS3 or HTML5 player. Currently, the loop parameter only works in the AS3 player when used in conjunction with the playlist parameter. To loop a single video, set the loop parameter value to 1 and set the playlist parameter value to the same video ID already specified in the Player API URL.
It appears that the loop parameter requires the playlist param as well, - I'm adding the note from YouTube's documentation.
Note: This parameter has limited support in the AS3 player and in IFrame embeds, which could load either the AS3 or HTML5 player. Currently, the loop parameter only works in the AS3 player when used in conjunction with the playlist parameter. To loop a single video, set the loop parameter value to 1 and set the playlist parameter value to the same video ID already specified in the Player API URL:
SEE ALL OPTIONS descriptions CLICK here
autohide
autoplay
cc_load_policy
color
controls
disablekb
enablejsapi
end
fs
hl
iv_load_policy
list
listType
loop
modestbranding
origin
playerapiid
playlist
playsinline
rel
showinfo
start
theme
use
playlist= you video embed
autoplay=1
and loop=1
try this and see
<iframe style="height:600px;width:100%" src="https://www.youtube.com/embed/ithw-xIyd_8?playlist=ithw-xIyd_8&loop=1&autoplay=1" frameborder="0" allowfullscreen" ></iframe>
it work powerful
My app allows users to embed videos from popular sites like youtube, etc. I have a text_area_field to accept the embed code as a string and save to the database. I am doing some basic validation with a regular expression to filter certain parts of the embed code. Sample embed code from youtube:
<iframe width="560" height="315" src="http://www.youtube.com/embed/INx7B2yyD0g" frameborder="0" allowfullscreen></iframe>
When i display the video back to the user i do this in my view
<%= user.content.html_safe %>
What i would like to know, is the following:
1. Is is safe to call html_safe on user submitted data, what other options do i have
2. Is storing the embed code as a string type good practice
3. Are there are any loopholes for users to submit bad scripts
4. What can be done differently to prevent such attacks
thanks
You could go the route of using something like the sanitize gem with a custom whitelist. But since it would have to accept things like <iframes> that could get tricky.
The safest bet would probably be to use an HTML parser like nokogiri to parse out the specific needed values and insert them into your own template for each service.
For your example embed code:
<iframe width="560" height="315" src="http://www.youtube.com/embed/INx7B2yyD0g" frameborder="0" allowfullscreen></iframe>
You'd just need to grab something like:
{:with => 560, :height => 315, :youtube_id => 'INx7B2yyD0g'}
It's definitely more work since you'd have to have different parsers and templates for each different video service you supported. But it's the safest way I can think of to avoid malicious HTML injection.