I'm creating an application which plays youtube videos in C# (winform). Now i'd like to fire an event, or something like that, when the video has ended.
I'm using the webbrowser control and call a youtube video like this:
wbYoutube.Navigate("http://www.youtube.com/v/" + playString[1] + "?version=3&enablejsapi=1&autoplay=1");
playString[1] is the youtube video id (like rGJN5K2cV_8).
I've been trying to get this working a few days now, has anyone got an idea on how to achieve this? If it's even possible...
If you need more info, let me know.
Thanks
I think this is possible but you have to write the html code into the browser element by yourself
wbYoutube.DocumentText = "";
Here is the html (You have to escape it)
<html><head></head><body>
<script type='text/javascript' src='http://www.youtube.com/player_api'></script>
<iframe id="player" width="100%" height="100%" src="http://www.youtube.com/embed/VIDEO_ID?autoplay=1&controls=0&enablejsapi=1" frameborder="0" allowfullscreen></iframe>
<script type="text/javascript">
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
videoId: 'VIDEO_ID',
events: {
'onStateChange': function(evt){
if(evt.data == 0){
window.external.Test('Video finished!!');
}
}
}
});
}
</script>
</body></html>
And have a look at Implement Two-Way Communication Between DHTML Code and Client Application Code
There you find the rest of the code.
Related
I have different YouTube video id's to play in iframe, at present only one video playing at a time, for handling next video i tried onPlayerStateChange() event, but event not fires when video is ended, is there any way to fire an event when video is ended or play multiple video one after another. any one please help me.
i have tried this below code.
html code:
<script type="text/javascript">
function ifplayer_onPlayerStateChange() {
alert("statechanged");
}
</script>
<iframe id="ifplayer" runat="server"/>
cs code:
ifplayer.Attributes.Add("src", "//www.youtube.com/embed/videoid");
ifplayer.Attributes.Add("onload", "ifplayer_onPlayerStateChange();");
I tired this below code to play another video after first video ended, it's working for me.
<iframe class="ytplayer" src="https://www.youtube.com/watch?v=pwfnT4CKoJo?enablejsapi=1" id="player" height="500" width="600" runat="server"></iframe>
<script>
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player( 'player', {
events: { 'onStateChange': onPlayerStateChange },
});
}
function onPlayerStateChange(event) {
switch(event.data) {
case 0:
document.getElementById('player').src = "https://www.youtube.com/watch?v=bhGQSsuTjmw?enablejsapi=1";
onYouTubeIframeAPIReady();
break;
case 1:
alert('video playing from ' + player.getCurrentTime());
break;
case 2:
alert('video paused at ' + player.getCurrentTime
break;
}
}
</script>
I would recommend taking a look at the YouTube API First and see if that can take away some of the work you need to do as google might have already created a solution to that.
You can find it here: https://developers.google.com/youtube/code_samples
I am using Xamarin to develop a cross-platform mobile app for both Android and iPhone. In my app I have to programmatically play a YouTube video. For the Android part I used a bind version of the official YouTube library and I have finished it without problem.
For the iPhone part I am unable to find a working library that could let me programmatically play the YouTube video.
I have tried the YouTube iframe API sample code from the following link: https://developers.google.com/youtube/iframe_api_reference#Getting_Started
The code I used is like this:
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
In the browser from my desktop, it auto-start the video after it is loaded using the startVideo() method. It works perfectly fine on desktop browser until I bring it to the iOS web view. It can load the video but it does not auto-start, which is one of our customer's requirement.
I understand that there are iOS library which could do the auto-play feature, but as I lack the knowledge on iOS native development, I am unable to do the iOS binding process.
I have tried other solutions like the followings:
https://github.com/afalz/YTHelper
https://github.com/nodoid/YoutubeBindings/tree/master/GoogleYoutube
But none of the above could work.
Any suggestion on how to do the auto-play feature in Xamarin?
I'm building a web application on ASP.NET with C#.
On a button click I show a loading image, while the database query is being executed. Then I dynamically create an Excel file and send it to the client like this:
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".xlsx");
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.Unicode;
HttpContext.Current.Response.BinaryWrite(p.GetAsByteArray());
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
I get the dialog box, and the loading image stays there.
I've tried placing call to a javascript function (with ClientScript.RegisterStartupScript function) before the code above, it didn't work. As I understand all javascript code is run after all the code-behind has executed, but in this case it doesn't execute at all once the file is sent to the client.
I've also tried creating a separate thread, and removing the loading image there. I put the breakpoint to trace it, code in the thread does execute, but the image still stays there.
Does anyone have an idea how this can be handled? Thank you!
You can only send or transmit 1 mime type in one request/response cycle. (My knowledge in this area is debatable).
That said, you can design a hack around this. Use an iframe on the client to "download the file". You can point its src to an ashx file that does the same.
You need to wire the iframe's onload event, so your web page has someway of knowing that download is done; thats where you can execute your logic.
Solution Update:
Well, after digging around, I've discovered my answer is half-baked!
The issue is that iframes don't trigger their onload event after they download something. The onload event will trigger iff there the url pointed to by src actually navigates to a different page. This is by design I suppose. And I learn that today!
So what then is the work-around?!
Fortunately, you can transmit cookies to the client. On the client your web page has to keep polling for the presence of this cookie. So once your web page is able to detect the presence of the cookie, it means that the browser has completed with the download request. This has been discussed in great detail in the following post:
http://geekswithblogs.net/GruffCode/archive/2010/10/28/detecting-the-file-download-dialog-in-the-browser.aspx
I'll just show you some code relating to the handler file (which simulates a download), and the client (which has an iframe doing the job). This should pretty much give you the gist:
Webform1.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.FileDownload.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>iFrame Download</title>
<script type="text/javascript" src="Scripts/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="Scripts/jquery.cookie.js"></script>
<script type="text/javascript">
function foo() {
console.log('foo');
//execute post-download logic here
}
$(function () {
$('input').click(function () {
//make sure we get rid of the
//cookie before download
$.removeCookie('downloaded');
var intrvl = setTimeout(function () { //this function polls for the cookie through which we track that the file has indeed been downloaded
console.log('timer');
var value = $.cookie('downloaded');
if (value == 'true') {
clearTimeout(intrvl);
foo();
}
}, 1000);
//this initiates the download
$('iframe').attr({
'src': 'download.ashx?id=' + $('#tbxRandomNumber').val()
});
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="tbxRandomNumber" runat="server"></asp:TextBox>
<input type="button" value="Download" />
<iframe src="about:blank" style="display:none"></iframe>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Next Random Number" />
</div>
</form>
</body>
</html>
I've made used of jquery cookies plugin to help me with handling cookies.
download.ashx:
using System;
using System.Web;
namespace WebApp.FileDownload
{
/// <summary>
/// Summary description for download
/// </summary>
public class download : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.SetCookie(new HttpCookie("downloaded","true")); //setting cookie in the response
string id = context.Request.QueryString["id"] == null ? "NULL" : context.Request.QueryString["id"];
string str = string.Format("Content with id {0} was generated at {1}", id, DateTime.Now.ToLongTimeString());
context.Response.AddHeader("Content-Disposition", "attachment; filename=test.txt");
context.Response.AddHeader("Content-Length", str.Length.ToString());
context.Response.Write(str);
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
It looks like you have a couple of misunderstandings here. You only have one request, and one response from the server. Making new threads is something that only happens on the server, and won't create additional responses.
When you're sending the Excel file, you're using:
HttpContext.Current.Response.Clear();
By clearing the response, you're losing the JavaScript that you added previously. It will never get to the client.
If the processing is fairly trivial (always just a couple of seconds), I'd just set the loading animation to run for a couple of seconds and stop, by setting a timeout on the initial onclick event. It's not perfect, but it'll give the user some immediate feedback.
If the processing is going to take a long or very variable amount of time, then the animation is more important to get right. You can try loading your Excel file in a hidden <iframe>, and attaching an onload event to remove the loading animation.
You would need to create a separate page to handle generating the Excel file, rather than doing it in a server-side OnClick handler. However, I seem to remember that support for onload events on <iframe> can be spotty with older IE versions.
javascript run in the client when page is loading in the browser. You may have a hidden textbox, at the end of you event yo can put a value into that textbox:
txtHidden.Text = "Hola Mundo"
You have to check the value on page load:
<script type="text/javascript">
$(document).ready(function(){
if($("#txtHidden").length > 0 && $("#txtHidden").val() != '')
{
alert($("#txtHidden").val());
}
});
</script>
You can put this in a web user control.
Another solution:
<div class='button' id='btnGenerateDownload' onClick='GenerateDownload(this)'>
Click here <div id='loadingImage' class='loadingImage'></div>
</div>
JQuery:
function GenerateDownload(caller)
{
//add loading gif:
var $loagingGIF = $(caller).children('#loadingImage').eq(0);
$loagingGIF.addClass('loadingImage');
var fileGeneratorUrl = 'ghFileGenerator.ashx';
var downloadHandlerUrl = 'ghDownloadHandler.ashx';
$.post({data: "File1"}, function(response){
//remove gif
$loagingGIF.removeClass('loadingImage');
if(response != '') //file key
{
downloadHandlerUrl += '?key=' + response;
var $link = $("<a />").attr('href', downloadHandlerUrl).html('download');
$link.appendTo($(caller));
}
});
}
css:
.loadingImage{background: transparent url(images/loading.gif);}
.ashx:
string filekey = context.Current.Request.Form("key");
There are many similar questions already, but for some reason they do not solve my issue.
My project is to save a dynamically created page (or part of the page). The user will have the option to drag objects on screen and leave them in any order and then for this order to be saved to disc as an image.
My own research shows that I can use Draggable from JQuery and this is easy to implement. It is the saving part where I am stuck.
I followed a few links, but the image does not appear to be saving to disc and I don't think it works in IE! However, I'm happy with FireFox and so using the toDataUrl() sounds like the best approach.
Since I couldn't get it work I decided to change tactic slightly and pass the value to the code behind (C#)
The save part of my code looks like
<script>
function SaveMe() {
var canvas = document.getElementById("mycanvas");
var image = canvas.toDataUrl();
document.getElementById("hideMe").value = image;
}
</script>
When I debug in FireBug, I never reach document.getElementById("hideMe").value = image;. I step through but can never get past var image = canvas.toDataUrl(); Is this expected behavior as I assume not but there is no error message?
The body of my HTML is
<body>
<script type="text/javascript">
$(document).ready(function () {
$('.popup_click').show(0).draggable();
});
</script>
<form id="form1" runat="server">
<div class="popup_click">
<div id="popup_title">Title</div>
</div>
<canvas id="mycanvas" class="canvas"></canvas>
<asp:HiddenField ID="hideMe" runat="server" />
<asp:Button runat="server" OnClick="ClickMe" text="Click" OnClientClick="SaveMe()"/>
</form>
</body>
What am I doing wrong? I'm working locally in debug mode, Visual Studio 2013.
Not absolutely sure, but I also had a problem with todataurl() in the past and this link helped me
Not able to get data url when using images in kinetic js
This is the function I always use when wanting to export a canvas to image, it puts the image into a popup window so the user can do what they want with it (I hope this helps):
function imageCanvas(evt){
var imageCanvas = document.createElement('canvas');
imageCanvas.width = document.documentElement.clientWidth;
imageCanvas.height = document.documentElement.clientHeight;
var imageCanvasContext = imageCanvas.getContext("2d");
imageCanvasContext.fillStyle = document.getElementById("body").style.backgroundColor;
imageCanvasContext.fillRect(0,0,imageCanvas.width,imageCanvas.height);
imageCanvasContext.drawImage(mainCanvas,0,0,imageCanvas.width,imageCanvas.height,0,0,imageCanvas.width,imageCanvas.height);
var dataURL = imageCanvas.toDataURL("image/png");
var imagePopup = window.open("","fractalLineImage","left=0,top=0,width="+(imageCanvas.width/2)+",height="+(imageCanvas.height/2)+",toolbar=0,resizable=0");
imagePopup.document.write("<title>Export Image</title>");
imagePopup.document.write("<img id='exportImage'"
+" alt=''"
+" height='"+ imageCanvas.height+"'"
+" width='"+ imageCanvas.width+"'"
+" style='position:absolute;left:0;top:0'/>");
imagePopup.document.close();
var exportImage = imagePopup.document.getElementById("exportImage");
exportImage.src = dataURL;
}
i have an iframe that which source need to be updated and refreshed. the way i want to do it is to click on an and with it's onclick function, i need to send something like myiframe.Attributes["src"] = "blah.aspx";
is there any quick way to do this?
thanks in advance
You can use javascript to send an AJAX query back to the server with the frame's source.
The javascript you could use is iframe.location.href where 'iframe' is the id attribute of your iframe.
Then you can send a callback to the server using ASP.NET AJAX (or another ajax call if you wish). Here is a good tutorial: http://ajax.net-tutorials.com/
You could do it all client side if you wanted to (untested code):
...
<body>
<a id="yourAnchorId">Load It</a>
<iframe id="youriFrameId" src="blank.html" width="500" height="400"></iframe>
<script type="text/javascript">
document.getElementById('yourAnchorId').onclick = function() {
var frame = document.getElementById('youriFrameId')
frame.src = "blah.aspx;"
frame.location.reload();
};
</script>
</body>
...