使用Javascript或HTML检测iOS设备的型号?

时间:2012-06-06 20:35:03

标签: javascript iphone html mediaelement.js device-detection

所以我在我的网站上提供H.264 .mp4视频。我使用的是开源HTML5视频播放器http://mediaelementjs.com/。一些访问者正在从Safari for iPhone查看。 iPhone 4仅支持高达720p的视频播放,因此如果我将视频设置为小于此值,则可以使用4和4S。但4S支持高达1080p的视频。那么我如何为4S提供更大的视频,为4提供更小的视频呢?我试过这个:

<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>

但它没有用。 iPhone 4不够智能,无法尝试第二个来源。如何让我的网站为不同的设备提供正确的视频?

11 个答案:

答案 0 :(得分:9)

在iPhone 4上播放720p视频 - 在iPhone 4S上播放1080p视频

在iPhone 4和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>

说明

加载1080p视频,然后使用Javascript的onError回退到720p。

Safari将嗅探1080p文件的标题以确定它是否可播放,如果它太大而无法解码则会引发错误。然后我们捕获该错误以提供720p视频。

通过使用这种功能检测,后备功能不仅适用于一台设备(iPhone 4),而且可能适用于许多不同功能的浏览器。

为什么多个<source>不起作用

当使用具有相同MIME类型的多个<source>标记时,浏览器将加载具有兼容MIME类型的第一个源并丢弃其他源,即使该视频无法播放。这是因为source元素are expected提供了替代视频编解码器(例如ogg,webm,mp4),替代帧大小/文件大小。

答案 1 :(得分:2)

以下是如何解决这个问题:

  

1)使用wurfl

检索设备模型
<script type='text/javascript' src=“//wurfl.io/wurfl.js"></script>

您可以使用HTTP或HTTPS(两者都受支持)如果您计划使用脚本提供的设备信息来做出渲染决策,那么您可能希望将脚本包含在元素中。否则,您可以异步加载它。现在,您可以在JavaScript中访问WURFL对象。

示例响应类似于:

  

{complete_device_name:“Apple iPhone 5”,form_factor:“智能手机”,   is_mobile:true}

当然你可以(而且应该)

console.log(WURFL);

找出你可以使用的其他属性。

  

2)现在你知道你的用户究竟是哪个设备型号了   在,您可以切换视频播放器配置。

怎么样?

<video width="IPHONE5_VIDEO_WIDTH"
       height="IPHONE5_VIDEO_HEIGHT"
       id="player" controls="controls"
       preload="auto">
       <source src="IPHONE5_VIDEO_URL" type="video/mp4">
</video>

超级干净,可读性对吗? 希望有所帮助。

答案 2 :(得分:1)

我有一个PHP脚本来执行此操作。我在这里得到它 - http://detectmobilebrowsers.com/ - 是的,有一个javascript,JQuery等版本。它对我们来说效果很好,它的好处似乎是保持相当的更新。我们遇到的唯一问题是iPad被故意设置为不将自己标识为移动设备。

答案 3 :(得分:0)

尝试this链接 该库应该能够检测用户代理,您可以相应地提供适当的文件。

答案 4 :(得分:0)

我无法提供示例代码,因为我不是Apple的极客,但我可以根据我的经验告诉您,尝试在XHTML和HTML5之间兼容网站,检查浏览器功能比浏览器版本更好。

原因是浏览器版本太多无法证明维护,并且还可以修改用户代理字符串。我建议您编写一个脚本,使用简单的if语句检查HTML5视频功能,然后根据结果呈现一个视频或另一个视频。

答案 5 :(得分:0)

如果视频是您正在检查的唯一功能,则像WURFL(无线通用资源文件 - http://wurfl.sourceforge.net/)或DeviceAtlas这样的移动设备检测数据库可能会过度。但它 是一种快速的方法,可以为更大范围的设备获得强大的功能检测,而不是可以编译检查,并且如果您的站点需要验证其他功能,它会派上用场除了视频支持。

答案 6 :(得分:0)

由于亲爱的@Duvrai提到的原因,你的解决方案不起作用。 我已经搜索到了达到你的目的的正确方法,似乎我们别无选择,除非使用一些javascript代码(这里不考虑服务器端编程)来决定应该交付哪个源。下面的代码段检测到浏览器 Type 及其 版本

&#13;
&#13;
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(' '));
})();
&#13;
&#13;
&#13;

现在您可以在javascript中编写一些代码行,并决定根据浏览器 Type Version 更改视频源。

答案 7 :(得分:0)

MEJS播放器无法正确处理错误,我还要添加更多支持以便能够检测到实际发生的情况。在iPhone上它甚至有时会抛出错误事件,但没有实际错误,你可以正确播放视频。

打开mediaelement-and-player.js并查找

        // 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);

然后使用此代码:

        // 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);

如果您需要,可以添加自己的处理,如果视频不受支持,将切换到720p。

在mediaelementplayer.css中添加此内容(不确定是否实际需要或只是改进我的主题):

/* 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 */

这适用于版本2.13.1,不确定新版本是否更好。

更新:最新版本2.16.3包含完全相同的无用错误处理程序。

答案 8 :(得分:-1)

这将检测iOS版本。也许它很有用:

if (navigator.userAgent.indexOf('5_0') != -1) {
    alert('IOS 5');
} else {
    alert('Other');
}

编辑: 我已经调整了脚本并对其进行了测试。

答案 9 :(得分:-1)

将其放入您的代码中:

<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>

答案 10 :(得分:-1)

我使用此代码:

    // 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>');
    }