2016-01-18 12:07:26 -07:00
|
|
|
|
define(['browser'], function (browser) {
|
2016-10-02 20:49:52 -07:00
|
|
|
|
'use strict';
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
2016-01-06 13:16:16 -07:00
|
|
|
|
function canPlayH264() {
|
|
|
|
|
var v = document.createElement('video');
|
|
|
|
|
return !!(v.canPlayType && v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, ''));
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 05:30:47 -07:00
|
|
|
|
function canPlayH265() {
|
2016-09-07 10:17:26 -07:00
|
|
|
|
|
|
|
|
|
if (browser.tizen) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 05:30:47 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-26 11:35:53 -07:00
|
|
|
|
var _supportsTextTracks;
|
|
|
|
|
function supportsTextTracks() {
|
|
|
|
|
|
|
|
|
|
if (_supportsTextTracks == null) {
|
|
|
|
|
_supportsTextTracks = document.createElement('video').textTracks != null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For now, until ready
|
|
|
|
|
return _supportsTextTracks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var _canPlayHls;
|
|
|
|
|
function canPlayHls(src) {
|
|
|
|
|
|
|
|
|
|
if (_canPlayHls == null) {
|
2016-01-18 12:07:26 -07:00
|
|
|
|
_canPlayHls = canPlayNativeHls() || canPlayHlsWithMSE();
|
2015-12-26 11:35:53 -07:00
|
|
|
|
}
|
|
|
|
|
return _canPlayHls;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function canPlayNativeHls() {
|
|
|
|
|
var media = document.createElement('video');
|
|
|
|
|
|
|
|
|
|
if (media.canPlayType('application/x-mpegURL').replace(/no/, '') ||
|
|
|
|
|
media.canPlayType('application/vnd.apple.mpegURL').replace(/no/, '')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-18 12:07:26 -07:00
|
|
|
|
function canPlayHlsWithMSE() {
|
2016-09-18 09:08:32 -07:00
|
|
|
|
if (window.MediaSource != null) {
|
2016-01-23 12:03:59 -07:00
|
|
|
|
// text tracks don’t work with this in firefox
|
2016-02-26 10:15:06 -07:00
|
|
|
|
return true;
|
2016-01-23 12:03:59 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function canPlayAudioFormat(format) {
|
|
|
|
|
|
|
|
|
|
var typeString;
|
|
|
|
|
|
2016-10-02 20:49:52 -07:00
|
|
|
|
if (format === 'flac') {
|
2016-06-25 13:18:23 -07:00
|
|
|
|
if (browser.tizen) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2016-09-06 20:38:01 -07:00
|
|
|
|
if (browser.edgeUwp) {
|
2016-07-27 22:19:24 -07:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2016-06-25 13:18:23 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 20:49:52 -07:00
|
|
|
|
else if (format === 'wma') {
|
2016-06-25 13:18:23 -07:00
|
|
|
|
if (browser.tizen) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2016-09-06 20:38:01 -07:00
|
|
|
|
if (browser.edgeUwp) {
|
2016-07-27 22:19:24 -07:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2016-06-25 13:18:23 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 20:49:52 -07:00
|
|
|
|
else if (format === 'opus') {
|
2016-01-23 12:03:59 -07:00
|
|
|
|
typeString = 'audio/ogg; codecs="opus"';
|
2016-02-06 13:31:52 -07:00
|
|
|
|
|
|
|
|
|
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-02 20:49:52 -07:00
|
|
|
|
if (format === 'webma') {
|
2016-01-23 12:03:59 -07:00
|
|
|
|
typeString = 'audio/webm';
|
|
|
|
|
} else {
|
|
|
|
|
typeString = 'audio/' + format;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (document.createElement('audio').canPlayType(typeString).replace(/no/, '')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2016-01-18 12:07:26 -07:00
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-27 22:19:24 -07:00
|
|
|
|
function testCanPlayMkv(videoTestElement) {
|
|
|
|
|
|
|
|
|
|
if (videoTestElement.canPlayType('video/x-matroska') ||
|
|
|
|
|
videoTestElement.canPlayType('video/mkv')) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var userAgent = navigator.userAgent.toLowerCase();
|
|
|
|
|
|
|
|
|
|
// Unfortunately there's no real way to detect mkv support
|
|
|
|
|
if (browser.chrome) {
|
2016-04-29 21:02:36 -07:00
|
|
|
|
|
2016-03-11 20:29:37 -07:00
|
|
|
|
// Not supported on opera tv
|
|
|
|
|
if (browser.operaTv) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-04-29 21:02:36 -07:00
|
|
|
|
|
|
|
|
|
// Filter out browsers based on chromium that don't support mkv
|
2016-10-02 20:49:52 -07:00
|
|
|
|
if (userAgent.indexOf('vivaldi') !== -1 || userAgent.indexOf('opera') !== -1) {
|
2016-04-29 21:02:36 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2016-03-11 20:29:37 -07:00
|
|
|
|
|
2016-03-10 10:59:32 -07:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
if (browser.tizen) {
|
2016-03-10 10:59:32 -07:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:38:01 -07:00
|
|
|
|
if (browser.edgeUwp) {
|
2016-07-27 22:19:24 -07:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 10:59:32 -07:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function testCanPlayTs() {
|
|
|
|
|
|
2016-09-21 23:57:31 -07:00
|
|
|
|
return browser.tizen || browser.web0s || browser.edgeUwp;
|
2016-03-10 13:07:23 -07:00
|
|
|
|
}
|
2016-03-10 10:59:32 -07:00
|
|
|
|
|
2016-07-28 13:21:54 -07:00
|
|
|
|
function getDirectPlayProfileForVideoContainer(container, videoAudioCodecs) {
|
2016-03-10 13:07:23 -07:00
|
|
|
|
|
|
|
|
|
var supported = false;
|
2016-07-28 13:21:54 -07:00
|
|
|
|
var profileContainer = container;
|
2016-09-21 23:57:31 -07:00
|
|
|
|
var videoCodecs = [];
|
2016-03-10 13:07:23 -07:00
|
|
|
|
|
|
|
|
|
switch (container) {
|
|
|
|
|
|
2016-07-27 22:19:24 -07:00
|
|
|
|
case 'asf':
|
2016-09-06 20:38:01 -07:00
|
|
|
|
supported = browser.tizen || browser.edgeUwp;
|
2016-07-28 13:21:54 -07:00
|
|
|
|
videoAudioCodecs = [];
|
2016-07-27 22:19:24 -07:00
|
|
|
|
break;
|
2016-03-10 13:07:23 -07:00
|
|
|
|
case 'avi':
|
2016-09-26 11:59:18 -07:00
|
|
|
|
supported = browser.tizen || browser.edgeUwp;
|
2016-07-28 13:21:54 -07:00
|
|
|
|
break;
|
2016-03-10 13:07:23 -07:00
|
|
|
|
case 'mpg':
|
|
|
|
|
case 'mpeg':
|
2016-12-17 22:35:28 -07:00
|
|
|
|
supported = browser.edgeUwp || browser.tizen;
|
2016-07-28 13:21:54 -07:00
|
|
|
|
break;
|
|
|
|
|
case '3gp':
|
|
|
|
|
case 'flv':
|
2016-03-10 13:07:23 -07:00
|
|
|
|
case 'mts':
|
|
|
|
|
case 'trp':
|
|
|
|
|
case 'vob':
|
|
|
|
|
case 'vro':
|
|
|
|
|
supported = browser.tizen;
|
|
|
|
|
break;
|
2016-07-28 13:21:54 -07:00
|
|
|
|
case 'mov':
|
2016-12-17 22:35:28 -07:00
|
|
|
|
supported = browser.tizen || browser.chrome || browser.edgeUwp;
|
2016-09-21 23:57:31 -07:00
|
|
|
|
videoCodecs.push('h264');
|
2016-07-28 13:21:54 -07:00
|
|
|
|
break;
|
2016-03-10 13:07:23 -07:00
|
|
|
|
case 'm2ts':
|
2016-09-06 20:38:01 -07:00
|
|
|
|
supported = browser.tizen || browser.web0s || browser.edgeUwp;
|
2016-09-21 23:57:31 -07:00
|
|
|
|
videoCodecs.push('h264');
|
2016-03-10 13:07:23 -07:00
|
|
|
|
break;
|
2016-07-27 22:19:24 -07:00
|
|
|
|
case 'wmv':
|
2016-09-06 20:38:01 -07:00
|
|
|
|
supported = browser.tizen || browser.web0s || browser.edgeUwp;
|
2016-07-28 13:21:54 -07:00
|
|
|
|
videoAudioCodecs = [];
|
2016-07-27 22:19:24 -07:00
|
|
|
|
break;
|
2016-03-11 20:29:37 -07:00
|
|
|
|
case 'ts':
|
2016-09-21 23:57:31 -07:00
|
|
|
|
supported = testCanPlayTs();
|
|
|
|
|
videoCodecs.push('h264');
|
2016-12-17 22:35:28 -07:00
|
|
|
|
if (canPlayH265()) {
|
|
|
|
|
videoCodecs.push('h265');
|
|
|
|
|
videoCodecs.push('hevc');
|
|
|
|
|
}
|
2016-07-28 13:21:54 -07:00
|
|
|
|
profileContainer = 'ts,mpegts';
|
2016-03-11 20:29:37 -07:00
|
|
|
|
break;
|
2016-03-10 13:07:23 -07:00
|
|
|
|
default:
|
|
|
|
|
break;
|
2016-03-10 10:59:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
if (!supported) {
|
|
|
|
|
return null;
|
2016-03-10 10:59:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
return {
|
2016-07-28 13:21:54 -07:00
|
|
|
|
Container: profileContainer,
|
|
|
|
|
Type: 'Video',
|
2016-09-21 23:57:31 -07:00
|
|
|
|
VideoCodec: videoCodecs.join(','),
|
2016-07-28 13:21:54 -07:00
|
|
|
|
AudioCodec: videoAudioCodecs.join(',')
|
2016-03-10 13:07:23 -07:00
|
|
|
|
};
|
2016-03-10 10:59:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
function getMaxBitrate() {
|
2016-03-10 10:59:32 -07:00
|
|
|
|
|
2016-09-07 10:17:26 -07:00
|
|
|
|
if (browser.edgeUwp) {
|
2016-12-17 22:35:28 -07:00
|
|
|
|
return 40000000;
|
2016-09-07 10:17:26 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-23 20:06:51 -07:00
|
|
|
|
// 10mbps
|
2016-09-07 10:17:26 -07:00
|
|
|
|
if (browser.xboxOne) {
|
2016-05-23 20:06:51 -07:00
|
|
|
|
return 10000000;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-20 13:45:50 -07:00
|
|
|
|
if (browser.ps4) {
|
|
|
|
|
return 8000000;
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 10:59:32 -07:00
|
|
|
|
var userAgent = navigator.userAgent.toLowerCase();
|
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
if (browser.tizen) {
|
2016-03-10 10:59:32 -07:00
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
// 2015 models
|
2016-10-02 20:49:52 -07:00
|
|
|
|
if (userAgent.indexOf('tizen 2.3') !== -1) {
|
2016-03-10 13:07:23 -07:00
|
|
|
|
return 20000000;
|
|
|
|
|
}
|
2016-03-10 10:59:32 -07:00
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
// 2016 models
|
|
|
|
|
return 40000000;
|
2016-03-10 10:59:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
return 100000000;
|
2016-03-10 10:59:32 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-04-04 12:55:39 -07:00
|
|
|
|
return function (options) {
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
2016-04-04 12:55:39 -07:00
|
|
|
|
options = options || {};
|
2016-12-19 22:22:31 -07:00
|
|
|
|
var physicalAudioChannels = options.audioChannels || (browser.tv || browser.xboxOne || browser.ps4 || !browser.mobile ? 6 : 2);
|
2016-05-14 11:02:06 -07:00
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
var bitrateSetting = getMaxBitrate();
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
2016-01-23 12:03:59 -07:00
|
|
|
|
var videoTestElement = document.createElement('video');
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
2016-01-23 12:03:59 -07:00
|
|
|
|
var canPlayWebm = videoTestElement.canPlayType('video/webm').replace(/no/, '');
|
2016-03-10 10:59:32 -07:00
|
|
|
|
|
2016-07-27 22:19:24 -07:00
|
|
|
|
var canPlayMkv = testCanPlayMkv(videoTestElement);
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
|
|
|
|
var profile = {};
|
|
|
|
|
|
|
|
|
|
profile.MaxStreamingBitrate = bitrateSetting;
|
|
|
|
|
profile.MaxStaticBitrate = 100000000;
|
|
|
|
|
profile.MusicStreamingTranscodingBitrate = Math.min(bitrateSetting, 192000);
|
|
|
|
|
|
|
|
|
|
profile.DirectPlayProfiles = [];
|
|
|
|
|
|
2016-01-07 22:44:45 -07:00
|
|
|
|
var videoAudioCodecs = [];
|
2016-02-13 19:26:51 -07:00
|
|
|
|
var hlsVideoAudioCodecs = [];
|
2016-01-13 22:18:46 -07:00
|
|
|
|
|
2016-01-25 13:28:29 -07:00
|
|
|
|
var supportsMp3VideoAudio = videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.69"').replace(/no/, '') ||
|
|
|
|
|
videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.6B"').replace(/no/, '');
|
|
|
|
|
|
2016-01-13 22:18:46 -07:00
|
|
|
|
// Only put mp3 first if mkv support is there
|
|
|
|
|
// Otherwise with HLS and mp3 audio we're seeing some browsers
|
2016-09-03 10:58:23 -07:00
|
|
|
|
// safari is lying
|
2016-12-17 22:35:28 -07:00
|
|
|
|
if ((videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/, '') && !browser.osx && !browser.iOS) || browser.edgeUwp || browser.tizen || browser.web0s) {
|
2016-11-03 09:54:56 -07:00
|
|
|
|
videoAudioCodecs.push('ac3');
|
|
|
|
|
|
|
|
|
|
// This works in edge desktop, but not mobile
|
|
|
|
|
// TODO: Retest this on mobile
|
2016-12-17 22:35:28 -07:00
|
|
|
|
if (!browser.edge || !browser.touch || browser.edgeUwp) {
|
2016-11-03 09:54:56 -07:00
|
|
|
|
hlsVideoAudioCodecs.push('ac3');
|
2016-02-02 19:12:02 -07:00
|
|
|
|
}
|
2016-01-30 11:31:31 -07:00
|
|
|
|
}
|
2016-03-10 10:59:32 -07:00
|
|
|
|
|
2016-12-17 22:35:28 -07:00
|
|
|
|
if (browser.tizen) {
|
|
|
|
|
videoAudioCodecs.push('eac3');
|
|
|
|
|
hlsVideoAudioCodecs.push('eac3');
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 10:59:32 -07:00
|
|
|
|
var mp3Added = false;
|
2016-09-21 23:57:31 -07:00
|
|
|
|
if (canPlayMkv) {
|
2016-06-26 09:21:10 -07:00
|
|
|
|
if (supportsMp3VideoAudio) {
|
2016-03-10 10:59:32 -07:00
|
|
|
|
mp3Added = true;
|
2016-01-13 22:18:46 -07:00
|
|
|
|
videoAudioCodecs.push('mp3');
|
|
|
|
|
}
|
2016-01-07 22:44:45 -07:00
|
|
|
|
}
|
2016-01-25 13:28:29 -07:00
|
|
|
|
if (videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"').replace(/no/, '')) {
|
2016-01-07 22:44:45 -07:00
|
|
|
|
videoAudioCodecs.push('aac');
|
2016-02-13 19:26:51 -07:00
|
|
|
|
hlsVideoAudioCodecs.push('aac');
|
2016-01-07 22:44:45 -07:00
|
|
|
|
}
|
2016-09-20 09:51:16 -07:00
|
|
|
|
if (supportsMp3VideoAudio) {
|
|
|
|
|
if (!mp3Added) {
|
|
|
|
|
videoAudioCodecs.push('mp3');
|
|
|
|
|
}
|
2016-12-17 22:35:28 -07:00
|
|
|
|
if (!browser.ps4) {
|
|
|
|
|
// PS4 fails to load HLS with mp3 audio
|
|
|
|
|
hlsVideoAudioCodecs.push('mp3');
|
|
|
|
|
}
|
2016-01-13 22:18:46 -07:00
|
|
|
|
}
|
2016-01-07 22:44:45 -07:00
|
|
|
|
|
2016-12-17 22:35:28 -07:00
|
|
|
|
if (browser.tizen || options.supportsDts) {
|
2016-09-09 09:58:08 -07:00
|
|
|
|
videoAudioCodecs.push('dca');
|
|
|
|
|
videoAudioCodecs.push('dts');
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-19 22:22:31 -07:00
|
|
|
|
if (options.supportsTrueHd) {
|
|
|
|
|
videoAudioCodecs.push('truehd');
|
2016-07-31 10:58:06 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-17 22:35:28 -07:00
|
|
|
|
videoAudioCodecs = videoAudioCodecs.filter(function (c) {
|
2016-11-03 09:54:56 -07:00
|
|
|
|
return (options.disableVideoAudioCodecs || []).indexOf(c) === -1;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
hlsVideoAudioCodecs = hlsVideoAudioCodecs.filter(function (c) {
|
|
|
|
|
return (options.disableHlsVideoAudioCodecs || []).indexOf(c) === -1;
|
|
|
|
|
});
|
|
|
|
|
|
2016-09-02 05:30:47 -07:00
|
|
|
|
var mp4VideoCodecs = [];
|
2016-01-23 12:03:59 -07:00
|
|
|
|
if (canPlayH264()) {
|
2016-09-02 05:30:47 -07:00
|
|
|
|
mp4VideoCodecs.push('h264');
|
|
|
|
|
}
|
|
|
|
|
if (canPlayH265()) {
|
|
|
|
|
mp4VideoCodecs.push('h265');
|
|
|
|
|
mp4VideoCodecs.push('hevc');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mp4VideoCodecs.length) {
|
2015-12-26 11:35:53 -07:00
|
|
|
|
profile.DirectPlayProfiles.push({
|
|
|
|
|
Container: 'mp4,m4v',
|
|
|
|
|
Type: 'Video',
|
2016-09-02 05:30:47 -07:00
|
|
|
|
VideoCodec: mp4VideoCodecs.join(','),
|
2016-01-07 22:44:45 -07:00
|
|
|
|
AudioCodec: videoAudioCodecs.join(',')
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-17 22:35:28 -07:00
|
|
|
|
if (browser.tizen) {
|
|
|
|
|
mp4VideoCodecs.push('mpeg2video');
|
|
|
|
|
mp4VideoCodecs.push('vc1');
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 05:30:47 -07:00
|
|
|
|
if (canPlayMkv && mp4VideoCodecs.length) {
|
2015-12-26 11:35:53 -07:00
|
|
|
|
profile.DirectPlayProfiles.push({
|
2016-07-28 13:21:54 -07:00
|
|
|
|
Container: 'mkv',
|
2015-12-26 11:35:53 -07:00
|
|
|
|
Type: 'Video',
|
2016-09-02 05:30:47 -07:00
|
|
|
|
VideoCodec: mp4VideoCodecs.join(','),
|
2016-01-07 22:44:45 -07:00
|
|
|
|
AudioCodec: videoAudioCodecs.join(',')
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|
2016-08-01 22:55:52 -07:00
|
|
|
|
|
2016-09-06 20:38:01 -07:00
|
|
|
|
if (browser.edgeUwp) {
|
2016-08-01 22:55:52 -07:00
|
|
|
|
profile.DirectPlayProfiles.push({
|
|
|
|
|
Container: 'mkv',
|
|
|
|
|
Type: 'Video',
|
|
|
|
|
VideoCodec: 'vc1',
|
|
|
|
|
AudioCodec: videoAudioCodecs.join(',')
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-12-26 11:35:53 -07:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 13:07:23 -07:00
|
|
|
|
// These are formats we can't test for but some devices will support
|
2016-07-28 13:21:54 -07:00
|
|
|
|
['m2ts', 'mov', 'wmv', 'ts', 'asf', 'avi', 'mpg', 'mpeg'].map(function (container) {
|
|
|
|
|
return getDirectPlayProfileForVideoContainer(container, videoAudioCodecs);
|
|
|
|
|
}).filter(function (i) {
|
2016-03-10 13:07:23 -07:00
|
|
|
|
return i != null;
|
|
|
|
|
}).forEach(function (i) {
|
|
|
|
|
profile.DirectPlayProfiles.push(i);
|
|
|
|
|
});
|
2016-03-10 10:59:32 -07:00
|
|
|
|
|
2016-07-28 13:21:54 -07:00
|
|
|
|
['opus', 'mp3', 'aac', 'flac', 'webma', 'wma', 'wav'].filter(canPlayAudioFormat).forEach(function (audioFormat) {
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
2016-01-23 12:03:59 -07:00
|
|
|
|
profile.DirectPlayProfiles.push({
|
2016-10-02 20:49:52 -07:00
|
|
|
|
Container: audioFormat === 'webma' ? 'webma,webm' : audioFormat,
|
2016-01-23 12:03:59 -07:00
|
|
|
|
Type: 'Audio'
|
|
|
|
|
});
|
2016-02-21 10:22:41 -07:00
|
|
|
|
|
|
|
|
|
// aac also appears in the m4a container
|
2016-10-02 20:49:52 -07:00
|
|
|
|
if (audioFormat === 'aac') {
|
2016-02-21 10:22:41 -07:00
|
|
|
|
profile.DirectPlayProfiles.push({
|
|
|
|
|
Container: 'm4a',
|
|
|
|
|
AudioCodec: audioFormat,
|
|
|
|
|
Type: 'Audio'
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (canPlayWebm) {
|
|
|
|
|
profile.DirectPlayProfiles.push({
|
|
|
|
|
Container: 'webm',
|
|
|
|
|
Type: 'Video'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
profile.TranscodingProfiles = [];
|
|
|
|
|
|
2016-12-17 22:35:28 -07:00
|
|
|
|
['opus', 'mp3', 'aac', 'wav'].filter(canPlayAudioFormat).forEach(function (audioFormat) {
|
2016-01-23 12:03:59 -07:00
|
|
|
|
|
|
|
|
|
profile.TranscodingProfiles.push({
|
|
|
|
|
Container: audioFormat,
|
|
|
|
|
Type: 'Audio',
|
|
|
|
|
AudioCodec: audioFormat,
|
|
|
|
|
Context: 'Streaming',
|
2016-12-17 22:35:28 -07:00
|
|
|
|
Protocol: 'http',
|
|
|
|
|
MaxAudioChannels: physicalAudioChannels.toString()
|
2016-01-23 12:03:59 -07:00
|
|
|
|
});
|
|
|
|
|
profile.TranscodingProfiles.push({
|
|
|
|
|
Container: audioFormat,
|
|
|
|
|
Type: 'Audio',
|
|
|
|
|
AudioCodec: audioFormat,
|
|
|
|
|
Context: 'Static',
|
2016-12-17 22:35:28 -07:00
|
|
|
|
Protocol: 'http',
|
|
|
|
|
MaxAudioChannels: physicalAudioChannels.toString()
|
2016-01-23 12:03:59 -07:00
|
|
|
|
});
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|
|
|
|
|
|
2016-06-26 09:21:10 -07:00
|
|
|
|
var copyTimestamps = false;
|
|
|
|
|
if (browser.chrome) {
|
|
|
|
|
copyTimestamps = true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-26 11:35:53 -07:00
|
|
|
|
// Can't use mkv on mobile because we have to use the native player controls and they won't be able to seek it
|
2016-09-18 09:08:32 -07:00
|
|
|
|
if (canPlayMkv && options.supportsCustomSeeking && !browser.tizen && options.enableMkvProgressive !== false) {
|
2015-12-26 11:35:53 -07:00
|
|
|
|
profile.TranscodingProfiles.push({
|
|
|
|
|
Container: 'mkv',
|
|
|
|
|
Type: 'Video',
|
2016-01-06 13:16:16 -07:00
|
|
|
|
AudioCodec: videoAudioCodecs.join(','),
|
2016-09-04 22:45:12 -07:00
|
|
|
|
VideoCodec: 'h264',
|
2016-02-19 23:57:17 -07:00
|
|
|
|
Context: 'Streaming',
|
2016-10-27 20:15:34 -07:00
|
|
|
|
MaxAudioChannels: physicalAudioChannels.toString(),
|
2016-06-26 09:21:10 -07:00
|
|
|
|
CopyTimestamps: copyTimestamps
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
2016-03-10 10:59:32 -07:00
|
|
|
|
|
2016-09-18 09:08:32 -07:00
|
|
|
|
if (canPlayHls() && options.enableHls !== false) {
|
2015-12-26 11:35:53 -07:00
|
|
|
|
profile.TranscodingProfiles.push({
|
|
|
|
|
Container: 'ts',
|
|
|
|
|
Type: 'Video',
|
2016-02-13 19:26:51 -07:00
|
|
|
|
AudioCodec: hlsVideoAudioCodecs.join(','),
|
2015-12-26 11:35:53 -07:00
|
|
|
|
VideoCodec: 'h264',
|
|
|
|
|
Context: 'Streaming',
|
2016-09-18 13:38:38 -07:00
|
|
|
|
Protocol: 'hls',
|
2016-10-16 10:11:32 -07:00
|
|
|
|
MaxAudioChannels: physicalAudioChannels.toString(),
|
2016-12-17 22:35:28 -07:00
|
|
|
|
EnableSplittingOnNonKeyFrames: (browser.osx || browser.iOS) ? true : false
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-13 22:40:01 -07:00
|
|
|
|
// Put mp4 ahead of webm
|
|
|
|
|
if (browser.firefox) {
|
|
|
|
|
profile.TranscodingProfiles.push({
|
|
|
|
|
Container: 'mp4',
|
|
|
|
|
Type: 'Video',
|
|
|
|
|
AudioCodec: videoAudioCodecs.join(','),
|
|
|
|
|
VideoCodec: 'h264',
|
|
|
|
|
Context: 'Streaming',
|
2016-05-14 11:02:06 -07:00
|
|
|
|
Protocol: 'http'
|
|
|
|
|
// Edit: Can't use this in firefox because we're seeing situations of no sound when downmixing from 6 channel to 2
|
|
|
|
|
//MaxAudioChannels: physicalAudioChannels.toString()
|
2016-05-13 22:40:01 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-26 11:35:53 -07:00
|
|
|
|
if (canPlayWebm) {
|
|
|
|
|
|
|
|
|
|
profile.TranscodingProfiles.push({
|
|
|
|
|
Container: 'webm',
|
|
|
|
|
Type: 'Video',
|
|
|
|
|
AudioCodec: 'vorbis',
|
|
|
|
|
VideoCodec: 'vpx',
|
|
|
|
|
Context: 'Streaming',
|
2016-05-14 11:02:06 -07:00
|
|
|
|
Protocol: 'http',
|
|
|
|
|
// If audio transcoding is needed, limit channels to number of physical audio channels
|
|
|
|
|
// Trying to transcode to 5 channels when there are only 2 speakers generally does not sound good
|
|
|
|
|
MaxAudioChannels: physicalAudioChannels.toString()
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
profile.TranscodingProfiles.push({
|
|
|
|
|
Container: 'mp4',
|
|
|
|
|
Type: 'Video',
|
2016-01-06 13:16:16 -07:00
|
|
|
|
AudioCodec: videoAudioCodecs.join(','),
|
2015-12-26 11:35:53 -07:00
|
|
|
|
VideoCodec: 'h264',
|
|
|
|
|
Context: 'Streaming',
|
2016-05-14 11:02:06 -07:00
|
|
|
|
Protocol: 'http',
|
|
|
|
|
// If audio transcoding is needed, limit channels to number of physical audio channels
|
|
|
|
|
// Trying to transcode to 5 channels when there are only 2 speakers generally does not sound good
|
|
|
|
|
MaxAudioChannels: physicalAudioChannels.toString()
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
profile.TranscodingProfiles.push({
|
|
|
|
|
Container: 'mp4',
|
|
|
|
|
Type: 'Video',
|
2016-01-06 13:16:16 -07:00
|
|
|
|
AudioCodec: videoAudioCodecs.join(','),
|
2015-12-26 11:35:53 -07:00
|
|
|
|
VideoCodec: 'h264',
|
|
|
|
|
Context: 'Static',
|
|
|
|
|
Protocol: 'http'
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
profile.ContainerProfiles = [];
|
|
|
|
|
|
|
|
|
|
profile.CodecProfiles = [];
|
2016-12-17 22:35:28 -07:00
|
|
|
|
|
|
|
|
|
var supportsSecondaryAudio = browser.tizen;
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
2016-01-25 13:28:29 -07:00
|
|
|
|
// Handle he-aac not supported
|
|
|
|
|
if (!videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.5"').replace(/no/, '')) {
|
|
|
|
|
profile.CodecProfiles.push({
|
|
|
|
|
Type: 'VideoAudio',
|
|
|
|
|
Codec: 'aac',
|
|
|
|
|
Conditions: [
|
|
|
|
|
{
|
|
|
|
|
Condition: 'NotEquals',
|
|
|
|
|
Property: 'AudioProfile',
|
|
|
|
|
Value: 'HE-AAC'
|
|
|
|
|
},
|
2016-05-14 11:02:06 -07:00
|
|
|
|
{
|
|
|
|
|
Condition: 'LessThanEqual',
|
|
|
|
|
Property: 'AudioBitrate',
|
|
|
|
|
Value: '128000'
|
2016-12-17 22:35:28 -07:00
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!supportsSecondaryAudio) {
|
|
|
|
|
profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
|
|
|
|
|
Condition: 'Equals',
|
|
|
|
|
Property: 'IsSecondaryAudio',
|
|
|
|
|
Value: 'false',
|
|
|
|
|
IsRequired: 'false'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!supportsSecondaryAudio) {
|
|
|
|
|
profile.CodecProfiles.push({
|
|
|
|
|
Type: 'VideoAudio',
|
|
|
|
|
Conditions: [
|
2016-01-25 13:28:29 -07:00
|
|
|
|
{
|
|
|
|
|
Condition: 'Equals',
|
|
|
|
|
Property: 'IsSecondaryAudio',
|
|
|
|
|
Value: 'false',
|
|
|
|
|
IsRequired: 'false'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
2016-04-30 11:34:46 -07:00
|
|
|
|
var maxLevel = '41';
|
|
|
|
|
|
|
|
|
|
if (browser.chrome && !browser.mobile) {
|
|
|
|
|
maxLevel = '51';
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-26 11:35:53 -07:00
|
|
|
|
profile.CodecProfiles.push({
|
|
|
|
|
Type: 'Video',
|
|
|
|
|
Codec: 'h264',
|
|
|
|
|
Conditions: [
|
|
|
|
|
{
|
|
|
|
|
Condition: 'NotEquals',
|
|
|
|
|
Property: 'IsAnamorphic',
|
|
|
|
|
Value: 'true',
|
|
|
|
|
IsRequired: false
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Condition: 'EqualsAny',
|
|
|
|
|
Property: 'VideoProfile',
|
|
|
|
|
Value: 'high|main|baseline|constrained baseline'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Condition: 'LessThanEqual',
|
|
|
|
|
Property: 'VideoLevel',
|
2016-04-30 11:34:46 -07:00
|
|
|
|
Value: maxLevel
|
2015-12-26 11:35:53 -07:00
|
|
|
|
}]
|
|
|
|
|
});
|
|
|
|
|
|
2016-10-03 22:15:39 -07:00
|
|
|
|
if (!browser.edgeUwp && !browser.tizen && !browser.web0s) {
|
2016-10-02 23:28:45 -07:00
|
|
|
|
profile.CodecProfiles[profile.CodecProfiles.length - 1].Conditions.push({
|
|
|
|
|
Condition: 'NotEquals',
|
|
|
|
|
Property: 'IsAVC',
|
|
|
|
|
Value: 'false',
|
|
|
|
|
IsRequired: false
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-26 11:35:53 -07:00
|
|
|
|
// Subtitle profiles
|
|
|
|
|
// External vtt or burn in
|
|
|
|
|
profile.SubtitleProfiles = [];
|
|
|
|
|
if (supportsTextTracks()) {
|
|
|
|
|
|
|
|
|
|
profile.SubtitleProfiles.push({
|
|
|
|
|
Format: 'vtt',
|
|
|
|
|
Method: 'External'
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
profile.ResponseProfiles = [];
|
|
|
|
|
|
|
|
|
|
profile.ResponseProfiles.push({
|
|
|
|
|
Type: 'Video',
|
|
|
|
|
Container: 'm4v',
|
|
|
|
|
MimeType: 'video/mp4'
|
|
|
|
|
});
|
|
|
|
|
|
2016-07-28 13:21:54 -07:00
|
|
|
|
if (browser.chrome) {
|
|
|
|
|
profile.ResponseProfiles.push({
|
|
|
|
|
Type: 'Video',
|
|
|
|
|
Container: 'mov',
|
|
|
|
|
MimeType: 'video/webm'
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-12-26 11:35:53 -07:00
|
|
|
|
|
|
|
|
|
return profile;
|
2016-04-04 12:55:39 -07:00
|
|
|
|
};
|
2015-12-26 11:35:53 -07:00
|
|
|
|
});
|