Changing youtube player parameters on already existing iframe - youtube-api

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>

Related

What would cause this youtube embed string to stop working?

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>

Blogspot Latex equation

I want to write Latex equation in Blogspot so I have chosen a dynamic template and pasted the HTML code after the <head> tag.
<script type="text/x-mathjax-config">
// <![CDATA[
MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [['\\[','\\]'], ['$$','$$']]}});
blogger.ui().viewType_.prototype.onRenderComplete=function(){MathJax.Hub.Queue(['Typeset',MathJax.Hub])};
// ]]>
</script>
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
After inserting some input I am not getting the Latex output. I have used another method but it is not working. How to fix it explicitly?
Forget the &quot and stuff. The latex output is not appearing in the Preview mode but it will appear properly when you publish that post.
Reason: the preview url is an https url and looks something like https://blogname.blogspot.com/b/post-preview?token=fsdbkdsbkjsdfnkjsdnf&postId=32798437243279&type=POST. Since the page is https your browser tries to load the script http://cdn.mathjax.org/mathjax/latest/MathJax.js also as https which generates a certificate error.
Since the viewers of your blog will never open it in https they won't ever face this problem. If you want to see the preview with correct latex output just click on Preview button. When the page loads replace https with http in the url and Bingo!!
Instead of playing with the blogger template, my solution is to use a plugin http://markdown-here.com/
Just write your equation like $sum_2^n{\pi}$
Note that there's no space between dollar sign and the equation.
Alternatively, another online markdown tool is https://stackedit.io/ . It's free and provides a direct output to Blogger. The pitfall is what you write is cached in the browser. When you have 10+ documents in the caches, there's a severe time lag in display.
For people who is not familiar with Latex equation, here is a reference: http://www.hostmath.com/

jQuery mobile force full reload when link clicked

I have a "normal" link in my jqm page like this:
<a href="http://www.mysite.com/mobile/page.php?attribute=value">
And if I click it it won't properly refresh taking into account the attribute value and loading everything that's needed for it dynamically based on the attribute value. I understand that this is due to the fact that jqm tries to do an ajax call like mentioned here:
When you use pageChange an Ajax request will be made to that url and it will be
loaded only the content inside the div with data-role="page". So everything you
have out of this element will be ignored (JS and CSS).
So, I found out in the docs that I should use $.mobile.ajaxEnabled=false; or rel=external on links or target=_blank on the link.
Strange thing though for me is that only when I set the target=_blank property to my links will this truly happen. So, am wondering if someone had this kind of a problem and how did you solve it? The thing is, I would like to refrain myself form using target=_blank as it opens a new tab in my browser (as expected, but this is not nice from users' POV).
jqm version I use is 1.2
This question now at the top of google search results, so figured I'd answer:
Use the data-ajax attribute and set it to false to force reload upon clicking a link:
data-ajax="false"
use it like:
<a href="/" data-ajax="false">
<img id="mainLogo" src="logo.svg" width="215" />
</a>
And then your link will force reload the page!
Linking without Ajax
Links that point to other domains or that have rel="external",
data-ajax="false" or target attributes will not be loaded with Ajax.
Instead, these links will cause a full page refresh with no animated
transition. Both attributes (rel="external" and data-ajax="false")
have the same effect, but a different semantic meaning: rel="external"
should be used when linking to another site or domain, while
data-ajax="false" is useful for simply opting a page within your
domain from being loaded via Ajax. Because of security restrictions,
the framework always opts links to external domains out of the Ajax
behavior.
Parts taken from https://stackoverflow.com/a/22951472
Make function for the onclick event of the link.See the below code example.Hope this helps!
<script type="text/javascript">
function loadPage(url){
document.location.href = url;
}
<script/>
<a href="#" onClick="loadPage('http://www.mysite.com/mobile/page.php?attribute=value');">

Changing address bar when using iframe

Is there a way to use an iframe, but still have the address bar change when clicking what's inside the iframe to what the page actually is? I want to have a horizontal bar at the top of the page with a music player that allows music to play while browsing the site. But I also want people to easily be able to bookmark the pages as well.
I've searched, but can't find the answer. Many are just looking to change what URL is loaded in the iframe...that's not what I want. I want the actual address bar displayed in the browser to update.
This sentence is here to help me reach the 30 character minimum. Ignore this and read the next sentence for your answer:
No.
UPDATE:
"Changing" and "Redirecting" are two different things. You need to clarify which it is. "Changing" the address bar is impossible.
"Redirecting" IS possible.
Clicking on a standard link from within an iframe will not affect the topmost window on its own. A quick example of a Javascript redirect within an iframe would be something like this:
TOP WINDOW:
<html>
<head></head>
<body>
<iframe src="http://yoursite.com/iframe_test.html" />
</body>
IFRAME TEST:
<html>
<head>
<script>
window.onload = ready;
function ready()
{
document.getElementById("link1").onclick = linkClick;
document.getElementById("link2").onclick = linkClick;
}
function linkClick(e)
{
e.preventDefault();
window.top.location.href = this.href;
}
</script>
</head>
<body>
<a id="link1" href="http://youtube.com">Link1</a>
<a id="link2" href="http://facebook.com">Link2</a>
</body>
EXPLANATION:
Without the Javascript in place, what will happen when you click on a link in an iframe is that you will remain on the original page and the iframe will be redirected to the link you've clicked on. Using Javascript within an iframe in this fashion can force the topmost frame to redirect.
I would highly discourage relying on this in any way. It's sloppy programming in general, and I would stay away from iframes altogether if possible.
Yes, you can, but it's not a straightforward solution and it has some limitations
changing
You can use Web API messages and history API together to get what you want.
Example
Jsfiddle
redirecting
You can use the example above and replace the push history with a window.location.replace
Please consider the snippet as a hint to get what you want. The example above is not well thought for security (i.e. iframe script is sending messages to the parent, irrespective of its origin).

Rendering complete page and not "progressively" (using struts 2 / tiles)

Is there a way to get struts 2 (using tiles) to build the whole page before sending it to the browser? I don't want the page to be build "progressively" in the browser one part at a time.
The main problem I'm trying to solve is that internet explorer 7 flashes/blinks the page even if only some of the content changes (firefox does this much more smoothly).
So that if I have a page with:
HEADER
some content
FOOTER
And the "some content" area only changes between page loads, the FOOTER part still flashes the white background before filling it with the background color of the footer. I tought that maybe by getting struts to send the complete page it would load fast enough to eliminate the "blinking".
Now the FOOTER comes from the server a little bit later than the parts before it and so it flashes (in internet explorer, firefox displays the page smoothly).
NB: this is an important requirement for the site, and using ajax to load the middle content is out (as are frames or other "hacks"). The site is built using CSS and not a table layout, maybe I will have to use a table layout to get it to work...
About using tiles flush parameter:
I tried that and it doesn't work as I need. I would need a flush-parameter for the whole page. I have tried the normal jsp page directive "autoFlush=false" but it didn't work. I set this directive on my main template page (and not in the tiles).
Here is an example from the main template, which uses header, body and footer templates. With the Thread.sleep() I added the problem is easy to spot. The footer renders 2 secs later than the rest of the page.
<body>
<div id="container">
<t:insertAttribute name="header" flush="false" />
<div id="content"><t:insertAttribute name="body" flush="false"/></div>
<div class="clear"></div>
<% Thread.sleep(2000); %>
<t:insertAttribute name="footer" flush="false" />
</div>
</body>
UPDATE
Thanks for the comments. The requirement is actually almost reasonable as this isn't a normal web page, think embedded.
But apparently there is no way of configuring IE to start rendering after some delay (like firefox has a configurable delay of some 100ms)?
I tried to intercept the TilesResult but the method doExecute is run before the whole content is apparently evaluated, so the method has already exited before the jsp is evaluated (my Thread.sleep() test). I was wondering how I could render the whole response to a string and then output that all at once to the browser.
I know that this isn't foolproof and network delays etc may factor in this, but if I could get the response to output all at once and maybe use a table based layout (IE possibly renders the table only after the table closes) this could work reasonably.
Or then try to get this switched to firefox or maybe forget all about this little glitch...
UPDATE 2
This started to bother me so I did some investigation.
If I had a plain jsp page (no tiles) the buffering works (with the buffer attribute), so that if I had my Thread.sleep() there the whole page rendered after two seconds if the page size was below the buffer size.
But if I used tiles in the page (as in the example above) I couldn't get the page to render at the same time (I even included the page directive in all my tiles-templates/"components", no help). So tiles probably flushes the response somewhere?
Furthermore, the "problematic tiles" was my body-part, which contained a struts:form tag. I replaced it with a normal form-tag and it worked as I wanted...
UPDATE 3
Ok, nobody seems to know the inner workings of tiles or struts tags...
No big problem as this is a very specific case and requirement.
I worked around it by using apache as a proxt in front of the application, and using apache's proxy configuration options to specify a large buffer.
I'll mark this as answered.
You can send page data all at once at the server end if you like (and many frameworks do that anyway for convenience) but the reality of networking is that it won't all arrive at once and the browser will render it as packets arrive. And this is a good thing for responsiveness, even if you* aesthetically would like the page to display all at once.
You can reduce the lag as much as possible by simplifying markup and using deflate compression to keep the payload size down, and that's a worthwhile thing to do in general. Plus you can make sure you're not hitting a Flash Of Unstyled Content. But you can't control when the browser chooses to render, short of doing it all in JavaScript with all the downsides that entails (and even then, the browser might redraw slowly).
(* - or your client/boss, if that's who has come up with this "important requirement" that your site somehow work differently to every other page on the web.)
Can you use the "flush" attribute on the tiles components?
<tiles:insertAttribute name="body" flush="false"/>
In addition if the output buffer gets too big, it will flush anyway. Try increasing the buffer size?
<%# page language="java" buffer="500kb" autoFlush="false" %>

Resources