Many people use the following to detect for iPad or iPhone.
<script>
var agent=navigator.userAgent.toLowerCase();
var useHTML5 = (agent.indexOf('iphone')!=-1 || agent.indexOf('ipad')!=-1);
if (useHTML5){
document.write("");
} else{
document.write("");
}
</script>
The Apple official way to detect only for ipad iphone is
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// iPad-specific code
} else {
// iPhone-specific code
}
But what if I also want to check for other mobile(at least Android devices anyways)?
Should I resort to Modernizr?
Or a script from
http://detectmobilebrowsers.com/ ?
Just want to add that in my particular case am using FancyBox with VideoJS.
MobileESP Project has a solid array of user-agent detecting methods in JavaScript too yet MobileESP API: JavaScript is very limited simply because some devices has no JavaScript support and a server side detection is the right way to do it. DeviceAtlas Products will provide more information about the device capabilities if needed yet has its price tag too...
Related
The code below works fine on desktop browsers (plays music). But when I try to open the site on any mobile device it doesn't work.
var music = new Audio("mscs/gamemusic.mp3");
function playmusic() {
music.controls = false;
music.loop = false;
music.autoplay = true;
document.body.appendChild(music)
}
I use it in a function when game starts:
function createnewgame() {
...
playmusic();
...
...
}
Does anyone know what's wrong?
Well, this is clearly a browser support issue. According to caniuse, the <audio> element (and js' Audio object is an interface used for it) has known support issues, including
iOS and Chrome on Android do not support autoplay as advised by the specification
and others. Not sure if this can be overcome by some library but since the limitation of autoplay was introduced by design, I wouldn't count on workarounds...
Instead of adding the var "music" to html body, you can try playing the audio directly from JavaScript.
function playmusic() {
music.play();
}
Some mobile browsers support automatic playback of audio, but ios, chrome and others require interactive actions to trigger the sound playback.You can try working with the mute attribute...enter link description here
I am trying to target specific browsers and depending on the browser I would like to display different links. My issues is that I have some pdf portfolios but they will only open in IE and the rest of the browsers give a message to download adobe reader.
My test code:
var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
//For Firefox
if (browser == 'Firefox') {
document.write('Download');
}
//For Safari
if (browser == 'Safari') {
document.write('<'+'a href="test.pdf" download="test.pdf">Download</a>');
}
//For Chrome
if (is_chrome) {
document.write('<'+'a href="test.pdf" download="test.pdf">Download</a>');
}
//For IE
if(document.documentMode) {
document.write('View PDF');
}
This is what I have pulled together from searching but is not working. I want to view the pdf if in IE or download it if it is in another browser.
Feature detection is recommended over browser detection but in your case I don't think that will help. Here is a good script to detect the browser: WhichBrowser
Today I get started in appmobi. I was developing a small example to deal with sounds.
I just needed to create a handler to play and stop many sounds.
var audioOn = new Audio('sounds/11.mp3');
audioOn.play();
This code is working in the xdk simulator, also on android devices, but not in my Iphone 5.
The thing is, if I use tag it works on iphone, but I want to use javascript native api to deal with sounds and more.
I have been trying to deal with it with appmobi player library but it comes without controls to stop, resume etc, thats way I want to use native.
Here is part of javascript code :
<script type="text/javascript">
/* This function runs once the page is loaded, but appMobi is not yet active */
var init = function(){
var alarmButton = document.getElementById("alarmButton");
var on = false;
//var audioOn = new Audio('http://rpg.hamsterrepublic.com/wiki-images/3/3e/Heal8-Bit.ogg');
var audioOn = new Audio('sounds/11.mp3');
audioOn.addEventListener('ended', function() {
this.play();
}, false);
var but = function(){
alert("but");
alert(on);
alert(audioOn);
if(!on){
on = true;
audioOn.currentTime = 0;
audioOn.play();
}
else{
on = false;
audioOn.pause();
}
}
//alarmButton.addEventListener("click",but,false);
alarmButton.addEventListener("touchstart",but,false);
alarmButton.addEventListener("tap",but,false);
};
window.addEventListener("load",init,false);
/* This code prevents users from dragging the page */
var preventDefaultScroll = function(event) {
event.preventDefault();
window.scroll(0,0);
return false;
};
document.addEventListener('touchmove', preventDefaultScroll, false);
/* This code is used to run as soon as appMobi activates */
var onDeviceReady=function(){
//Size the display to 768px by 1024px
AppMobi.display.useViewport(768,1024);
//hide splash screen
AppMobi.device.hideSplashScreen();
};
document.addEventListener("appMobi.device.ready",onDeviceReady,false);
function echo(){
alert("clicked");
}
</script>
Thanks a lot
It seems like its not appmobi issue.
I think appmobi lab app for iphone uses safari mobile to run the html5 tests.
So its a safari mobile affair.
It seems play() work when launched by an onclick event. See http://groups.google.com/group/iphonewebdev/browse_thread/thread/91e31ba7ae25e6d4?hl=en
Need to perform some tests...
I have to try this:
http://www.schillmania.com/projects/soundmanager2/
Supporting HTML5 audio can be tedious in modern browsers, let alone
legacy ones. With real-world visitors using browsers ranging from
mobile Safari to IE 6 across a wide range of devices, there can be
many support cases to consider.
SoundManager 2 gives you a single, powerful API that supports both new
and old, using HTML5 audio where supported and optional Flash-based
fallback where needed. Ideally when using SoundManager 2, audio "just
works."
So I'm serving H.264 .mp4 video on my website. I'm using open source HTML5 video player http://mediaelementjs.com/. Some visitors are viewing from Safari for iPhone. The iPhone 4 supports video playback only up to 720p, so if I make my videos smaller than that, they work on the 4 and the 4S. But the 4S supports video up to 1080p. So how would I serve a larger video to the 4S and a smaller video to the 4? I tried this:
<video width="640" height="400" id="player" controls="controls" preload="auto">
<source src="https://s3.amazonaws.com/my-big-1080p-video.mp4" type="video/mp4">
<source src="https://s3.amazonaws.com/my-small-720p-video.mp4" type="video/mp4">
</video>
But it didn't work. The iPhone 4 isn't smart enough to try the second source. How can I make my website serve the correct video to the different devices?
Play 720p video on iPhone 4 — 1080p video on iPhone 4S
Try this on an iPhone 4 and a 4S (jsfiddle)
<video src="http://file.brow.sr/1080p.mp4" onerror="this.src='http://file.brow.sr/720p.mp4';" controls loop width="320" height="180">
</video>
Explanation
Load the 1080p video, then use Javascript's onError to fall back to 720p.
Safari will sniff the header of the 1080p file to determine if it's playable, and if it's too big to decode it will throw an error. We then catch that error to provide the 720p video.
By using this kind of feature detection, the fallback will not only work on one device (iPhone 4) but probably on a lot of different capable browsers.
Why multiple <source>'s won't work
When using multiple <source> tags with the same MIME types, the browser will load the first source that has a compatible MIME type and discard the others, even if that video is not playable. That's because source elements are expected to provide alternative video codecs (eg. ogg, webm, mp4), not alternative frame sizes / file sizes.
Here is how to go about it:
1) Retrieve the device model by using wurfl
<script type='text/javascript' src=“//wurfl.io/wurfl.js"></script>
You can either use HTTP or HTTPS (both are are supported) If you plan to use the device information provided by the script to make rendering decisions, then you might want to include the script in the element. Otherwise, you can load it asynchronously. Now you have access to the WURFL object within JavaScript.
Sample response looks something like:
{ complete_device_name:"Apple iPhone 5", form_factor:"Smartphone",
is_mobile:true }
off course you can(and should)
console.log(WURFL);
to find out the rest of the properties you can use.
2) Now that you know which exactly which device model your users are
on, you can switch the video players configs.
How about something like?
<video width="IPHONE5_VIDEO_WIDTH"
height="IPHONE5_VIDEO_HEIGHT"
id="player" controls="controls"
preload="auto">
<source src="IPHONE5_VIDEO_URL" type="video/mp4">
</video>
super clean and readable right?
Hope that helps.
I have a php script that does this. I got it here - http://detectmobilebrowsers.com/ - and yes, there is a javascript, JQuery, etc. versions. It's worked quite well for us and it has the benefit of seeming to stay fairly updated. The only issue we've run into was an iPad that had been deliberate set not to identify itself as a mobile device.
Your solution don't work because of the reason mentioned by dear #Duvrai.
I've searched to attain a right way to meet your purpose and it seemed we have no choice unless using some javascript code (here without considering server side programming) to make a decision which source should be delivered. The bellow snippet detects the browser Type and its Version:
navigator.sayswho= (function(){
var ua= navigator.userAgent, tem,
M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if(/trident/i.test(M[1])){
tem= /\brv[ :]+(\d+)/g.exec(ua) || [];
alert('IE '+(tem[1] || ''));
}
if(M[1]=== 'Chrome'){
tem= ua.match(/\bOPR\/(\d+)/)
if(tem!= null) alert('Opera '+tem[1]);
}
M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
alert( M.join(' '));
})();
Now you can write some lines of code in javascript and decide to change video sources based on browser Type and Version.
Try this link
The library should be able to detect user-agent and you can serve appropriate files accordingly.
I cannot offer sample code since I am not an Apple geek, but I can tell you based off of my experience trying to make sites compatible between XHTML and HTML5 that it is better to check for browser capability than browser version.
The reason for this is that there are too many browser versions to justify the upkeep, and also the user agent string can be modified. I recommend that you write a script that checks for HTML5 video capabilities with a simple if statement, and then render either one video or the other depending upon the results.
A mobile device detection database like WURFL (Wireless Universal Resource File - http://wurfl.sourceforge.net/) or DeviceAtlas may be overkill if video is the only capability you're checking for. But it is a quick way to get robust capabilities detection for a vastly larger range of devices than you would be able to feasibly compile checks for, and would come in handy if your site ever needs to verify other capabilities besides video support.
MEJS player does not handle errors correctly, I'd to add more support to be able to detect what actually happened. On iPhone it even sometimes throws an error event but there is no actual error and you can play the video correctly.
Open mediaelement-and-player.js and look for
// error handling
media.addEventListener('error',function() {
loading.hide();
controls.find('.mejs-time-buffering').hide();
error.show();
error.find('mejs-overlay-error').html("Error loading this resource");
}, false);
Then use this code:
// error handling
media.addEventListener('error',function() {
var
videoError = error.closest('.mejs-inner').find('video,audio')[0].error,
msg = 'Error loading this resource.';
if (!videoError) { //webkit sometimes throws error event but video has no actual error and can play the video correctly - ignore the event
console.log('MEJS event: error throws but no error found - ignored');
return;
}
//hide elements visible while loading and playing - cannot play after error
loading.hide();
controls.addClass('hidden'); //controls are automatically displayed when mouse hover is detected - must hide it permanently using class with !important
error.closest('.mejs-inner').find('.mejs-overlay-play').hide(); //also hide overlay with play button
error.show();
//get relevant error message
switch(videoError.code) { //see http://www.w3.org/TR/html5/embedded-content-0.html#error-codes
case videoError.MEDIA_ERR_ABORTED: //loading stopped (by user, e.g. by pressing ESC or Back)
msg = 'Video loading aborted';
break;
case videoError.MEDIA_ERR_DECODE: //invalid format (actually presumed format is OK, but the data does not correspond with the defined format - probably corrupted file of data transfer)
msg = 'Video file is broken';
break;
case videoError.MEDIA_ERR_NETWORK: //network problem (was able to connect to the provided URL but could not get the video data)
msg = 'Network connection lost';
break;
case videoError.MEDIA_ERR_SRC_NOT_SUPPORTED: //invalid source URL (url provided does not lead to a supported video file)
msg = 'Video not supported';
break;
}
//display error
console.log('Video error: ' + msg + ', code: ' + videoError.code);
error.find('.mejs-overlay-error').html(msg);
}, false);
If you need to you can add your own handling that will switch to 720p in case of unsupported video.
And in mediaelementplayer.css add this (not sure if actually required or just improvement for my theme):
/* Display errors */
.mejs-overlay-error {
color: white;
background: black;
text-align: center;
font-size: 1.2EM;
}
.mejs-controls.hidden {
display: none !important;
}
/* End: Display errors */
This is for version 2.13.1, not sure if newer version is better.
Update: newest version 2.16.3 contains exactly same useless error handler.
This will detect the iOS version. Maybe it can be useful:
if (navigator.userAgent.indexOf('5_0') != -1) {
alert('IOS 5');
} else {
alert('Other');
}
Edit:
I have have ajusted and tested the script.
Put this in your tags:
<meta name="viewport" content="initial-scale=1.0">
<meta name="viewport" content="width=320.1">
<script>
if (window.screen.height==568) { // iPhone 5
document.querySelector("meta[name=viewport]").content="width=320.1";
// your code here
}
</script>
I use this code:
// iPhone 3
if (window.screen.height==480 && window.screen.width==320 && window.devicePixelRatio==1)
{
$('#chartDivWrapper').html('<div id="chartdiv" style="height:300px;width:500px;"></div>');
}
// iPhone 4, this is Retina
else if (window.screen.height==480 && window.screen.width==320 && window.devicePixelRatio==2)
{
$('#chartDivWrapper').html('<div id="chartdiv" style="height:300px;width:500px;"></div>');
}
// iPhone 5
else if (window.screen.height==568 && window.screen.width==320 && window.devicePixelRatio==2)
{
$('#chartDivWrapper').html('<div id="chartdiv" style="height:400px;width:600px;"></div>');
}
// iPad
else if (window.screen.height==1024 && window.screen.width==768 && window.devicePixelRatio==1)
{
$('#chartDivWrapper').html('<div id="chartdiv" style="height:425px;width:680px;"></div>');
}
// iPad Retina
else if (window.screen.height==1024 && window.screen.width==768 && window.devicePixelRatio==2)
{
$('#chartDivWrapper').html('<div id="chartdiv" style="height:425px;width:680px;"></div>');
}
// all other, this was before for all
else
{
$('#chartDivWrapper').html('<div id="chartdiv" style="height:400px;width:600px;"></div>');
}
I've got this in the <head>:
<script>
function log(event){
var Url = "./log.php?session=<?php echo session_id(); ?>&event=" + event;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", Url, true );
xmlHttp.send( null );
}
</script>
And this in the <body>:
<video id="video" src="./video/LarryVideo.mp4"
controls="controls"
poster="./img/video_poster.jpg"
onabort="log('onabort');"
oncanplay="log('oncanplay');"
oncanplaythrough="log('oncanplaythrough');"
ondurationchange="log('ondurationchange');"
onemptied="log('onemptied');"
onended="log('onended');"
onerror="log('onerror');"
onloadeddata="log('onloadeddata');"
onloadedmetadata="log('onloadedmetadata');"
onloadstart="log('onloadstart');"
onpause="log('onpause');"
onplay="log('onplay');"
onplaying="log('onplaying');"
onprogress="log('onprogress');"
onratechange="log('onratechange');"
onreadystatechange="log('onreadystatechange');"
onseeked="log('onseeked');"
onseeking="log('onseeking');"
onstalled="log('onstalled');"
onsuspend="log('onsuspend');"
ontimeupdate="log('ontimeupdate');"
onvolumechange="log('onvolumechange');"
onwaiting="log('onwaiting');">
<script>
QT_WriteOBJECT('./video/LarryVideo.mp4',
'380px', '285px', // width & height
'', // required version of the ActiveX control, we're OK with the default value
'scale', 'tofit', // scale to fit element size exactly so resizing works
'emb#id', 'video_embed', // ID for embed tag only
'obj#id', 'video_obj'); // ID for object tag only
</script>
</video>
My normal Safari creates nice log-file entries as expected. Mobile Safari from iPad however doesn't do anything at all.
What could be wrong with this?
I have not been able to get a hold of readystate on an ipad either, but you can get other events that more-or-less let you infer the readystate.
var audio = new Audio("someSource.mp3");
audio.play();
/* you may need to use .load() depending on how the event was initiated */
audio.addEventListener("canplay", handleCanPlay, false);
audio.addEventListener("durationchange", handleDurationChange, false);
But let's be clear, the problem is Apple pretty much telling the whole world they're using the internet wrong. Granted, everyone hates sites that start playing music the second they load, but then Apple goes nuts and kills ANY/ALL buffering of audio/video that isn't explicitly initiated by a user gesture because Apple, apparently, thinks their users can't hit "back" if a site bothers them; fanboys agree too. This basically leaves the rest of us to hack up our applications if we dare try and manage any kind of sound effects. I know this isn't the place to rant, but building ANY soft of interesting/interactive experience in HTML5 on the iPad is one facepalm after another -- be it the 5mb cache limit that simply crashes the browser if a page has "too" many (according to Apple) images, or the difficulty to preload any sort of media to enhance UI. Seriously, outside of Wordpress blogs and RSS readers, mobile Safari's implementation of HTML5 is pretty worthless. And so the dream of HTML5 "build once, play anywhere" value proposition is dead and we go back to developing native apps. At least this gives us good job security! /rant