I'm trying to use MediaElement.js on a site and everything works great in every browser but IE, most specifically IE9 (I'm not too concerned with supporting below IE9 at the moment). I'm populating the ME dynamically which I've read can cause problems in IE specifically, but I'm just not sure if there is a workaround. The reason I'm doing it this way is because this is a portfolio site where all project data gets loaded through a getJSON call and once loaded all projects get populated with their appropriate data and created on the fly. There are several video projects. I've dumbed the code down to an example outside of my project which essentially goes through this same behavior. If I just write the HTML out and control in JS it works but when I create the HTML through JS and then try to play I get the error log (in the creation of ME player in the code). Here is the code:
$(function() {
var details = {
width: 640,
height: 480,
src: 'work/television/1'
},
$body = $('body'),
$vid = $('<video width="' + details.width + '" height="' + details.height + '" preload="none" id="vidPlayer1"></video>'),
$mp4 = $('<source src="' + details.src + '.mp4" type="video/mp4" title="mp4">'),
$webm = $('<source src="' + details.src + '.webm" type="video/webm" title="webm">'),
$ogg = $('<source src="' + details.src + '.ogv" type="video/ogg" title="ogg">'),
$flash = $('<object width="' + details.width + '" height="' + details.height + '" type="application/x-shockwave-flash" data="swf/flashmediaelement.swf"><param name="movie" value="swf/flashmediaelement.swf"><param name="flashvars" value="controls=true&file=' + details.src + '.mp4"></object>'),
$error = $('<p>The available video formats are not supported by your browser. :(</p>'),
$controls = $('<div class="videoControls playBtn"></div>');
$body.append($controls);
$vid.append($mp4);
$vid.append($webm);
$vid.append($ogg);
$vid.append($flash);
$vid.insertAfter($controls);
var vidPlayer = new MediaElementPlayer('#vidPlayer1', {
features: [],
// mode: 'shim',
pluginPath: 'swf/',
success: function(mediaElement) {
console.log('success', mediaElement);
},
error: function() {
console.log('Error loading player. Please try again.');
}
});
$body.on('click', function(evt) {
vidPlayer.play();
});
});
Any help would be tremendously appreciated.
problem solved. for anyone interested, had to combine my appends into one call so $vid became:
$vid = $('<video width="' + details.width + '" height="' + details.height + '" preload="none" id="vidPlayer-' + row + '-' + slide + '"><source src="' + details.src + '.mp4" type="video/mp4" title="mp4"><source src="' + details.src + '.webm" type="video/webm" title="webm"><source src="' + details.src + '.ogv" type="video/ogg" title="ogg"><p>The available video formats are not supported by your browser. :(</p></video>')
just had to put it all in one statement and IE9 recognized it properly. The issue was by appending as I was doing the source variables never got appended and thus IE didn't know what the source of my video was.
Hope this helps someone in the future.
Related
UPDATE 1: I've created a GIST with actual running code in a test jig to show exactly what I'm running up against. I've included working bot tokens (to a throw-away bot) and access to a telegram chat that the bot is already in, in case anyone wants to take a quick peek. It's
https://gist.github.com/pleasantone/59efe5f9d7f0bf1259afa0c1ae5a05fe
UPDATE 2: I've looked at the following articles for answers already (and a ton more):
https://github.com/francois2metz/html5-formdata/blob/master/formdata.js
PhantomJS - Upload a file without submitting a form
https://groups.google.com/forum/#!topic/casperjs/CHq3ZndjV0k
How to instantiate a File object in JavaScript?
How to create a File object from binary data in JavaScript
I've got a program written in casperjs (phantomjs) that successfully sends messages to Telegram via the BOT API, but I'm pulling my hair out trying to figure out how to send up a photo.
I can access my photo either as a file, off the local filesystem, or I've already got it as a base64 encoded string (it's a casper screen capture).
I know my photo is good, because I can post it via CURL using:
curl -X POST "https://api.telegram.org/bot<token>/sendPhoto" -F chat_id=<id> -F photo=#/tmp/photo.png
I know my code for connecting to the bot api from within capserjs is working, as I can do a sendMessage, just not a sendPhoto.
function sendMultipartResponse(url, params) {
var boundary = '-------------------' + Math.floor(Math.random() * Math.pow(10, 8));
var content = [];
for (var index in params) {
content.push('--' + boundary + '\r\n');
var mimeHeader = 'Content-Disposition: form-data; name="' + index + '";';
if (params[index].filename)
mimeHeader += ' filename="' + params[index].filename + '";';
content.push(mimeHeader + '\r\n');
if (params[index].type)
content.push('Content-Type: ' + params[index].type + '\r\n');
var data = params[index].content || params[index];
// if (data.length !== undefined)
// content.push('Content-Length: ' + data.length + '\r\n');
content.push('' + '\r\n');
content.push(data + '\r\n');
};
content.push('--' + boundary + '--' + '\r\n');
utils.dump(content);
var xhr = new XMLHttpRequest();
xhr.open("POST", url, false);
if (true) {
/*
* Heck, try making the whole thing a Blob to avoid string conversions
*/
body = new Blob(content, {type: "multipart/form-data; boundary=" + boundary});
utils.dump(body);
} else {
/*
* this didn't work either, but both work perfectly for sendMessage
*/
body = content.join('');
xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
// xhr.setRequestHeader("Content-Length", body.length);
}
xhr.send(body);
casper.log(xhr.responseText, 'error');
};
Again, this is in a CASPERJS environment, not a nodejs environment, so I don't have things like fs.createReadableStream or the File() constructor.
I have the following script that I'm trying to run with PhantomJS v 1.9.8.
var page = require('webpage').create();
page.content =
"<!DOCTYPE html>" +
"<html> " +
" <head></head> " +
" <body> " +
" <h1>Test</h1> " +
" </body> " +
"</html>";
page.onLoadFinished = function(status) {
//page.render('C:\\PDFTemp\\test.pdf', { format: 'pdf' }); // <-- Works
page.render('/dev/stdout', { format: 'pdf' }); // <- Gives me 0 bytes
phantom.exit();
};
When I run the page.render to write as a file, it works perfectly. However, rendering to stdout gives me nothing.
Note: I'm running version 1.9.8. Version 2.0 doesn't like to play nice with ASP.Net, but 1.9.8 works great.
What am I doing wrong here?
I'm looking for a way to give my SharePoint users a way to create new wiki pages from an existing template. In the process of researching I found a great walkthrough that seems to fit the need (http://www.mssharepointtips.com/tip.asp?id=1072&page=2), but I'm having trouble getting it to work. The problem seems to lie in the assignment of a path to PATHTOWIKI-- if I use "/Weekly Update Wiki", the script returns an error of "There is no Web named '/Weekly Update Wiki'." If I use "Weekly Update Wiki" without the forward slash, I instead get an error of "There is no Web named '/sites/[parentSite]/[childSite]/Weekly Update Wiki/Weekly Update Wiki'."
Any ideas about what I'm not understanding here?
function myCreateProject() {
// Configure these for your environment
// include no slashes in paths
var PATHTOWIKI = "Weekly Update Wiki";
var PATHTOPAGES = "Pages";
// file name only for template page, no extension
var TEMPLATEFILENAME = "Template";
var myPathToWiki = encodeURIComponent(PATHTOWIKI);
var myPathToPages = PATHTOPAGES + "%2f";
var myTemplateFileName = encodeURIComponent(TEMPLATEFILENAME) + "%2easpx";
var EnteredProject = document.getElementById("NewProjName");
var myNewName = EnteredProject.value;
if(myNewName == "") {
alert('Please enter a name for the new project page');
} else {
myNewName = encodeURIComponent(myNewName) + "%2easpx"
$.ajax({
url: PATHTOWIKI + "/_vti_bin/_vti_aut/author.dll",
data: ( "method=move+document%3a14%2e0%2e0%2e4730&service%5fname="
+ myPathToWiki +
"&oldUrl=" + myPathToPages + myTemplateFileName +
"&newUrl=" + myPathToPages + myNewName +
"&url%5flist=%5b%5d&rename%5foption=nochangeall&put%5foption=edit&docopy=true"
),
success: function(data) {
var rpcmsg1 = getMessage(data, "message=", "<p>");
$("#myInfo").append("<br />" + rpcmsg1);
if(rpcmsg1.indexOf("successfully") < 0) {
// get error info
var rpcmsg2 = getMessage(data, "msg=", "<li>");
$("#myInfo").append("<br />" + rpcmsg2 + "<br />");
} else {
$("#myInfo").append("<br />Go to new page<br />");
}
},
type: "POST",
beforeSend: function(XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("X-Vermeer-Content-Type",
"application/x-www-form-urlencoded");
}
});
}
}
Update: I figured out what needed to happen in my case. Since I couldn't get a grasp on the relative approach, I just went with the absolute path for PATHTOWIKI and slightly modified the append in the ajax call.
PATHTOWIKI:
var PATHTOWIKI = "https://[domain]/sites/[parentSite]/[childSite]";
append:
$("#myInfo").append("<br />Go to new page<br />");
The change in the latter line of code is subtle; since I used an absolute path in PATHTOWIKI, I just removed the leading forward slash in the anchor tag, so that <a href=\"/" became <a href=\"". This renders the script slightly less portable, but since it's a one-off effort I'll stick with this unless anything comes along to expand the scope.
Can someone please help me out on this?
I have spent a considerable amount of time setting up PhantomJS to save JPGs of specific web-pages and it works/ed really well until I went to deploy it on a machine which accesses the net through a proxy.
Now, whatever I try, I can not get the authentication right?
Has anyone EVER managed to do this?
I am using command line arguments:
--proxy=xx.xx.xx.xx:8080
--proxy-type=http
--proxyAuth=myusername:mypassword
I have checked on the Proxy (TMG) which still insists that my username is anonymous rather than the one which I am sending through using the command line.
From the --debug, I am able to see that proxy, proxyType and proxyAuth have all been populated correctly so PhantomJS is understanding the command line, yet when it runs, it still returns 'Proxy requires authentication'
Where am I going wrong?
Thanks for reading this and, hopefully, helping me out
BTW - I am using Windows 7 - 64 bit
OK, so I've done a whole load of digging on this and have got it working. So I thought I would publish what I found in case it might help someone else.
One of the things that I found when I was searching around is that there was a bit of a discussion about the inclusion of the following in the headers which are submitted by the JS which is used to drive PhantomJS:
page.customHeaders={'Authorization': 'Basic '+btoa('username:password')};
rather than using
page.settings.userName = 'username';
page.settings.password = 'password';
which will not work. Please refer to Previous Discussion
This is fine if you are using basic levels of authentication on the proxy. It will not work if you are using Integrated Authetication as this will still require NTLM/Kerberos or whatever.
The way around this is to change the settings on the client.
You need to allow the client access to the outside world WITHOUT it routing through the proxy. Certainly in TMG, this is done by changing the settings which apply to the Client Network Software which is installed on the client hardware.
By allowing the PhantomJS Executable to bypass the proxy, you will overcome the problems which I and many others have experienced but you will still have a bit of an issue as you will have just broken your system security so be aware and hope that there is a new version PhantomJS which handles NTLM/Kerberos.
Alternatively, change your Proxy to use Basic Authentication which will allow the use to the customHeaders solution to work as above but this is potentially an even greater risk to you security than allowing the client to bypass the proxyy.
var page = require('webpage').create(),
system = require('system'),
fs = require('fs'),
fileName = 'phantomjs',
extension = 'log',
file = fs.open(fileName + '.' + extension, 'w'),
address,
output,
delay,
version = phantom.version.major + '.'
+ phantom.version.minor + '.'
+ phantom.version.patch ;
if (system.args.length === 1){
console.log('Usage: example.js <some URL> delay');
phantom.exit();
}
// Handle the command line arguments
address = system.args[1];
output = system.args[2];
delay = system.args[3];
// Write the Headers into the log file
file.writeLine("PhantomJS version: " + version);
file.writeLine("Opening page: " + address);
file.writeLine("Writing image to: " + output);
file.writeLine("Applying a delay of: " + delay + " milliseconds");
function quit(reason, value) {
console.log("Quit: " + reason);
file.writeLine("Quit: " + reason);
file.close();
if (value !== 1){
// If there has been an error reported, stick a datetime stamp on the log to retain it
var d = new Date();
var dateString = d.getFullYear().toString() +
((d.getMonth() + 1) <= 9 ? '0' : '') + (d.getMonth() + 1).toString() +
(d.getDate() <= 9 ? '0' : '') + d.getDate().toString() +
(d.getHours() <= 9 ? '0' : '') + d.getHours().toString() +
(d.getMinutes() <= 9 ? '0' : '') + d.getMinutes().toString() +
(d.getSeconds() <= 9 ? '0' : '') + d.getSeconds().toString();
fs.move(fileName + '.' + extension, fileName + '_' + dateString + '.' + extension);
}
phantom.exit(value);
}
page.onResourceError = function(resourceError) {
page.reason = resourceError.errorString;
page.reason_url = resourceError.url;
};
page.onError = function (msg, trace) {
console.log(msg);
file.writeLine(msg);
trace.forEach(function(item) {
console.log(' ', item.file, ':', item.line);
//file.writeLine(' ', item.file, ':', item.line);
})
quit("Failed", 0);
}
page.onResourceRequested = function (request) {
file.writeLine('Request: ' + JSON.stringify(request, undefined, 4));
};
page.onResourceReceived = function (response) {
file.writeLine('Receive: ' + JSON.stringify(response, undefined, 4));
};
// Set a user agent - if required
//page.settings.userAgent = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; .NET CLR 1.1.4322)';
// And open the page
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address: \"' + page.reason_url + '\": ' + page.reason);
file.writeLine('Unable to load the address: \"' + page.reason_url + '\": ' + page.reason);
quit("Failed", 0);
}
else {
window.setTimeout(function() {
console.log('Saving the page!');
file.writeLine('Saving the page!');
page.render(output);
quit("Finished", 1);
}, delay);
}
});
The example given for using ClientRowTemplate in the Kendo UI Grid uses a nasty HTML string
.ClientRowTemplate(
"<tr><td colspan=\"6\">" +
"<div class=\"customer-details\">" +
"<img src=\"" + #Url.Content("~/Content/web/Customers/") + "#=CustomerID#.jpg\"" +
"alt=\"#=ContactName#\" />" +
"<h3 class=\"k-widget\">#=ContactName#</h3>" +
"<dl>" +
"<dt>Name:</dt><dd>#=ContactName#</dd>" +
"<dt>Company:</dt><dd>#=CompanyName#</dd>" +
"<dt>Country:</dt><dd>#=Country#</dd>" +
"</dl>" +
"<dl >" +
"<dt>Address:</dt><dd>#=Address#</dd>" +
"<dt>Phone:</dt><dd>#=Phone#</dd>" +
"</dl>" +
"</div>" +
"</td></tr>"
)
I am currently using a partial view .ClientRowTemplate(Html.Partial("_ClientRowTemplate").ToHtmlString()), but it would be nice to have it in the same view file.
Is there a built-in way to use something a bit nicer like a <script id="rowTemplate" type="text/x-kendo-tmpl"> block? I would still like to use the Kendo MVC helpers and not JavaScript.
Check out Haacks blog on templated razor delegates. http://haacked.com/archive/2011/02/27/templated-razor-delegates.aspx/
Basically you can define a chunk of razor that will be rendered as HTML
Define you razor delegate
#{
Func<dynamic, object> tableRow = #<tr></tr>;
}
Then do this
.ClientRowTemplate( #tableRow(null).ToString() )