diff --git a/src/TizenVideo/TizenVideo.js b/src/TizenVideo/TizenVideo.js index 2433bd4..518a0f7 100644 --- a/src/TizenVideo/TizenVideo.js +++ b/src/TizenVideo/TizenVideo.js @@ -3,6 +3,7 @@ var cloneDeep = require('lodash.clonedeep'); var deepFreeze = require('deep-freeze'); var Color = require('color'); var ERROR = require('../error'); +var getTracksData = require('../tracksData'); function TizenVideo(options) { options = options || {}; @@ -148,6 +149,26 @@ function TizenVideo(options) { playbackSpeed: false }; + var gotTraktData = false; + var tracksData = { audio: [], subs: [] }; + + function retrieveExtendedTracks() { + if (!gotTraktData && stream !== null) { + gotTraktData = true; + getTracksData(stream.url, function(resp) { + if (resp) { + tracksData = resp; + } + if (((tracksData || {}).subs || []).length) { + onPropChanged('subtitlesTracks'); + } + if (((tracksData || {}).audio || []).length) { + onPropChanged('audioTracks'); + } + }); + } + } + function getProp(propName) { switch (propName) { case 'stream': { @@ -213,6 +234,14 @@ function TizenVideo(options) { extra = JSON.parse(textTrack.extra_info); } catch(e) {} var textTrackLang = typeof extra.track_lang === 'string' && extra.track_lang.length > 0 ? extra.track_lang.trim() : null; + if (((tracksData || {}).subs || []).length) { + var extendedTrackData = tracksData.subs.find(function(el) { + return (el || {}).id-1 === textTrack.index; + }); + if (extendedTrackData) { + textTrackLang = extendedTrackData.lang || 'eng'; + } + } textTracks.push({ id: textTrackId, lang: textTrackLang, @@ -307,6 +336,14 @@ function TizenVideo(options) { extra = JSON.parse(audioTrack.extra_info); } catch(e) {} var audioTrackLang = typeof extra.language === 'string' && extra.language.length > 0 ? extra.language : null; + if (((tracksData || {}).audio || []).length) { + var extendedTrackData = tracksData.audio.find(function(el) { + return (el || {}).id-1 === audioTrack.index; + }); + if (extendedTrackData) { + audioTrackLang = extendedTrackData.lang || 'eng'; + } + } audioTracks.push({ id: audioTrackId, lang: audioTrackLang, @@ -581,6 +618,16 @@ function TizenVideo(options) { } onPropChanged('buffering'); + var tizenVersion = false; + + try { + tizenVersion = parseFloat(global.tizen.systeminfo.getCapability('http://tizen.org/feature/platform.version')); + } catch(e) {} + + if (!tizenVersion || tizenVersion >= 6) { + retrieveExtendedTracks(); + } + window.webapis.avplay.open(stream.url); window.webapis.avplay.setDisplayRect(0, 0, window.innerWidth, window.innerHeight); window.webapis.avplay.setDisplayMethod('PLAYER_DISPLAY_MODE_LETTER_BOX'); diff --git a/src/WebOsVideo/WebOsVideo.js b/src/WebOsVideo/WebOsVideo.js index 4c3662a..02ace2c 100644 --- a/src/WebOsVideo/WebOsVideo.js +++ b/src/WebOsVideo/WebOsVideo.js @@ -2,6 +2,7 @@ var EventEmitter = require('eventemitter3'); var cloneDeep = require('lodash.clonedeep'); var deepFreeze = require('deep-freeze'); var ERROR = require('../error'); +var getTracksData = require('../tracksData'); function luna(params, call, fail, method) { if (call) params.onSuccess = call || function() {}; @@ -135,6 +136,47 @@ function stremioSubSizes(size) { return false; } +var device = { + unsupportedAudio: ['DTS', 'TRUEHD'], + unsupportedSubs: ['HDMV/PGS', 'VOBSUB'] +}; + +var fetchedDeviceInfo = false; + +function retrieveDeviceInfo() { + if (fetchedDeviceInfo) { + return; + } + window.webOS.service.request('luna://com.webos.service.config', { + method: 'getConfigs', + parameters: { + 'configNames': [ + 'tv.model.edidType' + ] + }, + onSuccess: function (result) { + if (((result || {}).configs || {})['tv.model.edidType']) { + fetchedDeviceInfo = true; + var edidType = result.configs['tv.model.edidType'].toLowerCase(); + if (edidType.includes('dts')) { + device.unsupportedAudio = device.unsupportedAudio.filter(function(e) { + return e !== 'DTS'; + }); + } + if (edidType.includes('truehd')) { + device.unsupportedAudio = device.unsupportedAudio.filter(function(e) { + return e !== 'TRUEHD'; + }); + } + } + }, + onFailure: function (err) { + // eslint-disable-next-line no-console + console.log('could not get deviceInfo', err); + } + }); +} + function WebOsVideo(options) { options = options || {}; @@ -146,14 +188,10 @@ function WebOsVideo(options) { var isLoaded = null; - var knownMediaId = false; - var subSize = 75; var disabledSubs = true; - var subscribed = false; - var currentSubTrack = false; var currentAudioTrack = false; @@ -173,140 +211,6 @@ function WebOsVideo(options) { char_opacity: 255 }; - var setSubs = function (info) { - textTracks = []; - if (info.numSubtitleTracks) { - for (var i = 0; i < info.subtitleTrackInfo.length; i++) { - var textTrack = info.subtitleTrackInfo[i]; - textTrack.index = i; - var textTrackLang = textTrack.language === '(null)' ? null : textTrack.language; - - var textTrackId = 'EMBEDDED_' + textTrack.index; - - if (!currentSubTrack && !textTracks.length) { - currentSubTrack = textTrackId; - } - - textTracks.push({ - id: textTrackId, - lang: textTrackLang, - label: textTrackLang, - origin: 'EMBEDDED', - embedded: true, - mode: textTrackId === currentSubTrack ? 'showing' : 'disabled', - }); - - } - onPropChanged('subtitlesTracks'); - onPropChanged('selectedSubtitlesTrackId'); - - } - }; - - var setTracks = function (info) { - audioTracks = []; - if (info.numAudioTracks) { - for (var i = 0; i < info.audioTrackInfo.length; i++) { - var audioTrack = info.audioTrackInfo[i]; - audioTrack.index = i; - var audioTrackId = 'EMBEDDED_' + audioTrack.index; - if (!currentAudioTrack && !audioTracks.length) { - currentAudioTrack = audioTrackId; - } - var audioTrackLang = audioTrack.language === '(null)' ? null : audioTrack.language; - audioTracks.push({ - id: audioTrackId, - lang: audioTrackLang, - label: audioTrackLang, - origin: 'EMBEDDED', - embedded: true, - mode: audioTrackId === currentAudioTrack ? 'showing' : 'disabled', - }); - } - onPropChanged('audioTracks'); - onPropChanged('selectedAudioTrackId'); - - } - }; - - var subscribe = function (cb) { - if (subscribed) return; - subscribed = true; - var answered = false; - luna({ - method: 'subscribe', - parameters: { - 'mediaId': knownMediaId, - 'subscribe': true - } - }, function (result) { - if (result.sourceInfo && !answered) { - answered = true; - var info = result.sourceInfo.programInfo[0]; - - setSubs(info); - - setTracks(info); - - unsubscribe(cb); - } - - if ((result.error || {}).errorCode) { - answered = true; - // console.error('luna playback error', result.error); - unsubscribe(cb); - // unsubscribe(); - // onVideoError(); - return; - } - - if ((result.unloadCompleted || {}).mediaId === knownMediaId && (result.unloadCompleted || {}).state) { - // strange case where it just.. ends? without ever getting result.sourceInfo - // onEnded(); - // console.log('strange case of end'); - // unsubscribe(cb); - return; - } - - count_message++; - - if (count_message === 30 && !answered) { - // cb(); - unsubscribe(cb); - } - }, function() { // function(err) - // console.log('luna error log 2'); - // console.error(err); - }); - }; - - var unsubscribe = function (cb) { - if (!subscribed) return; - subscribed = false; - luna({ - method: 'unsubscribe', - parameters: { - 'mediaId': knownMediaId - } - }, function () { // function(result) - // console.log('unsubscribe result', JSON.stringify(result)); - cb(); - }, function () { // function(err) - // console.log('unsubscribe error', JSON.stringify(err)); - cb(); - }); - cb(); - }; - - // var unload = function (cb) { - // luna({ - // method: 'unload', - // parameters: { - // 'mediaId': knownMediaId - // } - // }, cb, cb); - // }; - var toggleSubtitles = function (status) { if (!videoElement.mediaId) return; @@ -439,6 +343,69 @@ function WebOsVideo(options) { playbackSpeed: false }; + var gotTraktData = false; + var tracksData = { audio: [], subs: [] }; + + function retrieveExtendedTracks() { + if (!gotTraktData && stream !== null) { + gotTraktData = true; + getTracksData(stream.url, function(resp) { + var nrSubs = 0; + var nrAudio = 0; + textTracks = []; + audioTracks = []; + if (resp) { + tracksData = resp; + } + if (((tracksData || {}).subs || []).length) { + tracksData.subs.forEach(function(track) { + if (device.unsupportedSubs.includes(track.codec || '')) { + return; + } + var textTrackId = nrSubs; + nrSubs++; + if (!currentSubTrack && !textTracks.length) { + currentSubTrack = textTrackId; + } + textTracks.push({ + id: 'EMBEDDED_' + textTrackId, + lang: track.lang || 'eng', + label: track.lang || 'eng', + origin: 'EMBEDDED', + embedded: true, + mode: textTrackId === currentSubTrack ? 'showing' : 'disabled', + }); + }); + onPropChanged('subtitlesTracks'); + onPropChanged('selectedSubtitlesTrackId'); + } + if (((tracksData || {}).audio || []).length) { + tracksData.audio.forEach(function(track) { + if (device.unsupportedAudio.includes(track.codec || '')) { + return; + } + var audioTrackId = nrAudio; + nrAudio++; + if (!currentAudioTrack && !audioTracks.length) { + currentAudioTrack = audioTrackId; + } + audioTracks.push({ + id: 'EMBEDDED_' + audioTrackId, + lang: track.lang || 'eng', + label: track.lang || 'eng', + origin: 'EMBEDDED', + embedded: true, + mode: audioTrackId === currentAudioTrack ? 'showing' : 'disabled', + }); + }); + currentAudioTrack = 'EMBEDDED_0'; + onPropChanged('audioTracks'); + onPropChanged('selectedAudioTrackId'); + } + }); + } + } + function getProp(propName) { switch (propName) { case 'stream': { @@ -971,15 +938,18 @@ function WebOsVideo(options) { var initMediaId = function (cb) { function retrieveMediaId() { if (videoElement.mediaId) { - knownMediaId = videoElement.mediaId; clearInterval(timer); - subscribe(cb); + retrieveExtendedTracks(); + retrieveDeviceInfo(); + cb(); return; } count++; if (count > 4) { // console.log('failed to get media id'); clearInterval(timer); + retrieveExtendedTracks(); + retrieveDeviceInfo(); cb(); } } diff --git a/src/tracksData.js b/src/tracksData.js new file mode 100644 index 0000000..08db7fe --- /dev/null +++ b/src/tracksData.js @@ -0,0 +1,13 @@ +module.exports = function(url, cb) { + fetch('http://127.0.0.1:11470/tracks/'+encodeURIComponent(url)).then(function(resp) { + return resp.json(); + }).then(function(tracks) { + var audioTracks = tracks.filter(function(el) { return (el || {}).type === 'audio'; }); + var subsTracks = tracks.filter(function(el) { return (el || {}).type === 'text'; }); + cb({ audio: audioTracks, subs: subsTracks }); + }).catch(function(err) { + // eslint-disable-next-line no-console + console.error(err); + cb(false); + }); +};