Определить модель устройства iOS, используя Javascript или HTML?
Так что я размещаю видео H.264 .mp4 на моем сайте. Я использую видеоплеер с открытым исходным кодом HTML5 http://mediaelementjs.com/. Некоторые посетители просматривают с Safari для 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 ответов
Воспроизведение видео 720p на iPhone 4 - видео 1080p на iPhone 4S
Попробуйте это на 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>
не сработает
При использовании нескольких <source>
В тегах с одинаковыми типами MIME браузер загрузит первый источник с совместимым типом MIME и откажется от других, даже если это видео не воспроизводится. Это потому что source
ожидается, что элементы будут предоставлять альтернативные видеокодеки (например, ogg, webm, mp4), а не альтернативные размеры кадров / размеры файлов.
Вот как это сделать:
1) Получить модель устройства с помощью wurfl
<script type='text/javascript' src=“//wurfl.io/wurfl.js"></script>
Вы можете использовать HTTP или HTTPS (оба поддерживаются). Если вы планируете использовать информацию об устройстве, предоставленную сценарием, для принятия решений о рендеринге, возможно, вы захотите включить сценарий в элемент. В противном случае вы можете загрузить его асинхронно. Теперь у вас есть доступ к объекту WURFL в JavaScript.
Пример ответа выглядит примерно так:
{complete_device_name: "Apple iPhone 5", form_factor: "Smartphone", 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>
супер чистый и читабельный верно? Надеюсь, это поможет.
У меня есть PHP-скрипт, который делает это. Я получил это здесь - http://detectmobilebrowsers.com/ - и да, есть версии javascript, JQuery и т. Д. Это сработало довольно хорошо для нас, и у него есть преимущество в том, чтобы оставаться достаточно обновленным. Единственной проблемой, с которой мы столкнулись, был iPad, который был намеренно не идентифицирован как мобильное устройство.
Ваше решение не работает по причине, указанной уважаемым @Duvrai. Я искал, чтобы найти правильный способ удовлетворить вашу цель, и казалось, что у нас нет выбора, если только не использовать некоторый код JavaScript (здесь, без учета программирования на стороне сервера), чтобы принять решение, какой источник должен быть доставлен. Ниже приведен фрагмент кода, который определяет тип браузера и его версию:
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(' '));
})();
Теперь вы можете написать несколько строк кода в javascript и принять решение об изменении источников видео в зависимости от типа и версии браузера.
Попробуйте эту ссылку Библиотека должна быть в состоянии обнаружить пользовательский агент, и вы можете соответствующим образом обслуживать соответствующие файлы.
База данных обнаружения мобильных устройств, такая как WURFL (Wireless Universal Resource File - http://wurfl.sourceforge.net/) или DeviceAtlas, может быть излишней, если видео - единственная возможность, которую вы проверяете. Но это быстрый способ получить надежное обнаружение возможностей для значительно большего количества устройств, чем вы могли бы скомпилировать проверки, и он пригодится, если вашему сайту когда-нибудь понадобится проверить другие возможности, помимо поддержки видео.
Я не могу предложить пример кода, так как я не фанат Apple, но я могу сказать вам, основываясь на моем опыте, когда я пытался сделать сайты совместимыми с XHTML и HTML5, что лучше проверять возможности браузера, чем версию браузера.
Причина этого заключается в том, что существует слишком много версий браузера, чтобы оправдать поддержку, а также можно изменить строку пользовательского агента. Я рекомендую вам написать скрипт, который проверяет возможности видео HTML5 с помощью простого оператора if, а затем рендерить одно или другое видео в зависимости от результатов.
Плеер 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 содержит точно такой же бесполезный обработчик ошибок.
Это обнаружит версию iOS. Может быть, это может быть полезно:
if (navigator.userAgent.indexOf('5_0') != -1) {
alert('IOS 5');
} else {
alert('Other');
}
Изменить: я скорректировал и протестировал скрипт.
Поместите это в свои теги:
<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>
Я использую этот код:
// 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>');
}