diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 6b6b9ade..c7d21a74 100755 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -165,6 +165,7 @@ extjs_root(http_connection_t *hc, const char *remain, void *opaque) extjs_load(hq, "static/app/config.js"); extjs_load(hq, "static/app/tvhlog.js"); extjs_load(hq, "static/app/status.js"); + extjs_load(hq, "static/tv.js"); /** * Finally, the app itself diff --git a/src/webui/static/app/dvr.js b/src/webui/static/app/dvr.js index ee19b4d8..58caff7b 100644 --- a/src/webui/static/app/dvr.js +++ b/src/webui/static/app/dvr.js @@ -67,9 +67,8 @@ tvheadend.dvrDetails = function(entry) { if (entry.url != null && entry.filesize > 0) { content += '
' + 'Download ' - + parseInt(entry.filesize / 1000000) + ' MB
' - + "Play" + '
'; + + parseInt(entry.filesize / 1000000) + ' MB'; + } var win = new Ext.Window({ diff --git a/src/webui/static/app/epg.js b/src/webui/static/app/epg.js index 9b4a65c4..caa3639e 100755 --- a/src/webui/static/app/epg.js +++ b/src/webui/static/app/epg.js @@ -54,12 +54,6 @@ tvheadend.epgDetails = function(event) { content += '
' + event.ext_text + '
'; content += '
Search IMDB
' - - now = new Date(); - if (event.start < now && event.end > now) { - content += "
Play" + "
"; - } - content += ''; content += '
'; @@ -483,7 +477,7 @@ tvheadend.epg = function() { text : 'Watch TV', iconCls : 'eye', handler : function() { - new tvheadend.VLC(); + new tvheadend.VideoPlayer(); } }, '-', diff --git a/src/webui/static/app/ext.css b/src/webui/static/app/ext.css index b1a2f4f8..124dfbc5 100644 --- a/src/webui/static/app/ext.css +++ b/src/webui/static/app/ext.css @@ -333,6 +333,27 @@ padding: 10px; } +.tv-video-player { + margin-right: auto; + margin-left : auto; + + width : 100%; + height: 100%; + background: black; + color: white; +} + +.tv-video-idle { + background-image : url(../../docresources/tvheadendlogo.png); + background-repeat : no-repeat; + background-position : center; +} + +.tv-video-message { + text-align: center; + font-size: 150%; +} + .about-title { font-size: 24px; font-weight: bold; diff --git a/src/webui/static/app/tvheadend.js b/src/webui/static/app/tvheadend.js index 2fe9ec87..6effc4f5 100644 --- a/src/webui/static/app/tvheadend.js +++ b/src/webui/static/app/tvheadend.js @@ -50,192 +50,155 @@ Ext.Ajax.request({ }); /** - * Displays a mediaplayer using VLC plugin + * Displays a mediaplayer using the html5 video element */ -tvheadend.VLC = function(url) { +tvheadend.VideoPlayer = function(url) { - var vlc = Ext.get(document.createElement('embed')); - vlc.set({ - type : 'application/x-vlc-plugin', - pluginspage : 'http://www.videolan.org', - version : 'VideoLAN.VLCPlugin.2', - width : '100%', - height : '100%', - autoplay : 'no' - }); + var videoPlayer = new tv.ui.VideoPlayer({ + params: { + resolution: 384 + } + }); - var vlcPanel = new Ext.Panel({ - border : false, - layout : 'fit', - bodyStyle : 'background: transparent;', - contentEl: vlc - }); - - var missingPlugin = Ext.get(document.createElement('div')); - var missingPluginPanel = new Ext.Panel({ - border : false, - layout : 'fit', - bodyStyle : 'background: transparent;', - contentEl : missingPlugin - }); - - var selectChannel = new Ext.form.ComboBox({ - loadingText : 'Loading...', - width : 200, - displayField : 'name', - store : tvheadend.channels, - mode : 'local', - editable : false, - triggerAction : 'all', - emptyText : 'Select channel...' - }); + var selectChannel = new Ext.form.ComboBox({ + loadingText : 'Loading...', + width : 200, + displayField : 'val', + store : tvheadend.channels, + mode : 'local', + editable : false, + triggerAction : 'all', + emptyText : 'Select channel...' + }); - selectChannel.on('select', function(c, r) { - var streamurl = 'stream/channelid/' + r.data.chid; - var playlisturl = 'playlist/channelid/' + r.data.chid; + selectChannel.on('select', function(c, r) { + videoPlayer.zapTo(r.id); + }); - if (!vlc.dom.playlist || vlc.dom.playlist == 'undefined') { - var html = '

Embedded player could not be started.
You are probably missing VLC Mozilla plugin for your browser.

'; - html += '

M3U Playlist

'; - html += '

Direct URL

'; - missingPlugin.dom.innerHTML = html; - missingPluginPanel.show(); - vlcPanel.hide(); + var slider = new Ext.Slider({ + width : 135, + height : 20, + value : 90, + increment : 1, + minValue : 0, + maxValue : 100 + }); + + var sliderLabel = new Ext.form.Label(); + sliderLabel.setText("90%"); + slider.addListener('change', function() { + videoPlayer.setVolume(slider.getValue()); + sliderLabel.setText(videoPlayer.getVolume() + '%'); + }); + + var selectResolution = new Ext.form.ComboBox({ + width: 150, + displayField:'name', + valueField: 'res', + value: 384, + mode: 'local', + editable: false, + triggerAction: 'all', + emptyText: 'Select resolution...', + store: new Ext.data.SimpleStore({ + fields: ['res','name'], + id: 0, + data: [ + ['288','288p'], + ['384','384p'], + ['480','480p'], + ['576','576p'] + ] + }) + }); + + selectResolution.on('select', function(c, r) { + videoPlayer.setResolution(r.data.res); + if(videoPlayer.isIdle()) + return; + + var index = selectChannel.selectedIndex; + if(index < 0) + return; + + var ch = selectChannel.getStore().getAt(index); + videoPlayer.zapTo(ch.id); + }); + + var win = new Ext.Window({ + title : 'Live TV Player', + layout : 'fit', + width : 682 + 14, + height : 384 + 56, + constrainHeader : true, + iconCls : 'eye', + resizable : true, + tbar : [ + selectChannel, + '-', + { + iconCls : 'control_play', + tooltip : 'Play', + handler : function() { + if(!videoPlayer.isIdle()) { //probobly paused + videoPlayer.play(); + return; + } + + var index = selectChannel.selectedIndex; + if(index < 0) + return; + + var ch = selectChannel.getStore().getAt(index); + videoPlayer.zapTo(ch.id); } - else { - vlc.dom.playlist.stop(); - vlc.dom.playlist.items.clear(); - vlc.dom.playlist.add(streamurl); - vlc.dom.playlist.playItem(0); - vlc.dom.audio.volume = slider.getValue(); - missingPluginPanel.hide(); - vlcPanel.show(); + }, + { + iconCls : 'control_pause', + tooltip : 'Pause', + handler : function() { + videoPlayer.pause(); } - }); - - var slider = new Ext.Slider({ - width : 135, - height : 20, - value : 90, - increment : 1, - minValue : 0, - maxValue : 100 - }); - - var sliderLabel = new Ext.form.Label(); - sliderLabel.setText("90%"); - slider.addListener('change', function() { - if (vlc.dom.playlist && vlc.dom.playlist.isPlaying) { - vlc.dom.audio.volume = slider.getValue(); - sliderLabel.setText(vlc.dom.audio.volume + '%'); + }, + { + iconCls : 'control_stop', + tooltip : 'Stop', + handler : function() { + videoPlayer.stop(); } - else { - sliderLabel.setText(slider.getValue() + '%'); + }, + '-', + { + iconCls : 'control_fullscreen', + tooltip : 'Fullscreen', + handler : function() { + videoPlayer.fullscreen(); } - }); + }, + '-', + selectResolution, + '-', + { + iconCls : 'control_volume', + tooltip : 'Volume', + disabled : true + }, ], + items : [videoPlayer] + }); + + win.on('beforeShow', function() { + win.getTopToolbar().add(slider); + win.getTopToolbar().add(new Ext.Toolbar.Spacer()); + win.getTopToolbar().add(new Ext.Toolbar.Spacer()); + win.getTopToolbar().add(new Ext.Toolbar.Spacer()); + win.getTopToolbar().add(sliderLabel); + }); + + win.on('close', function() { + videoPlayer.stop(); + }); - var win = new Ext.Window({ - title : 'VLC Player', - layout : 'fit', - width : 507 + 14, - height : 384 + 56, - constrainHeader : true, - iconCls : 'eye', - resizable : true, - tbar : [ - selectChannel, - '-', - { - iconCls : 'control_play', - tooltip : 'Play', - handler : function() { - if (vlc.dom.playlist && vlc.dom.playlist.items.count - && !vlc.dom.playlist.isPlaying) { - vlc.dom.playlist.play(); - } - } - }, - { - iconCls : 'control_pause', - tooltip : 'Pause', - handler : function() { - if (vlc.dom.playlist && vlc.dom.playlist.items.count) { - vlc.dom.playlist.togglePause(); - } - } - }, - { - iconCls : 'control_stop', - tooltip : 'Stop', - handler : function() { - if (vlc.dom.playlist) { - vlc.dom.playlist.stop(); - } - } - }, - '-', - { - iconCls : 'control_fullscreen', - tooltip : 'Fullscreen', - handler : function() { - if (vlc.dom.playlist && vlc.dom.playlist.isPlaying - && (vlc.dom.VersionInfo.substr(0, 3) != '1.1')) { - vlc.dom.video.toggleFullscreen(); - } - else if (vlc.dom.VersionInfo.substr(0, 3) == '1.1') { - alert('Fullscreen mode is broken in VLC 1.1.x'); - } - } - }, '-', { - iconCls : 'control_volume', - tooltip : 'Volume', - disabled : true - }, ], - items : [ vlcPanel, missingPluginPanel ] - }); - - win.on('beforeShow', function() { - win.getTopToolbar().add(slider); - win.getTopToolbar().add(new Ext.Toolbar.Spacer()); - win.getTopToolbar().add(new Ext.Toolbar.Spacer()); - win.getTopToolbar().add(new Ext.Toolbar.Spacer()); - win.getTopToolbar().add(sliderLabel); - - // check if vlc plugin wasn't initialised correctly - if (!vlc.dom.playlist || (vlc.dom.playlist == 'undefined')) { - vlc.dom.style.display = 'none'; - var html = '

Embedded player could not be started.
You are probably missing VLC Mozilla plugin for your browser.

'; - - if (url) { - var channelid = url.substr(url.lastIndexOf('/')); - var streamurl = 'stream/channelid/' + channelid; - var playlisturl = 'playlist/channelid/' + channelid; - html += '

M3U Playlist

'; - html += '

Direct URL

'; - } - missingPlugin.dom.innerHTML = html; - vlcPanel.hide(); - } - else { - // check if the window was opened with an url-parameter - if (url) { - vlc.dom.playlist.items.clear(); - vlc.dom.playlist.add(url); - vlc.dom.playlist.playItem(0); - - //enable yadif2x deinterlacer for vlc > 1.1 - var point1 = vlc.dom.VersionInfo.indexOf('.'); - var point2 = vlc.dom.VersionInfo.indexOf('.', point1 + 1); - var majVersion = vlc.dom.VersionInfo.substring(0, point1); - var minVersion = vlc.dom.VersionInfo.substring(point1 + 1, point2); - if ((majVersion >= 1) && (minVersion >= 1)) - vlc.dom.video.deinterlace.enable("yadif2x"); - } - missingPluginPanel.hide(); - } - }); - - win.show(); + win.show(); }; /** diff --git a/src/webui/static/tv.js b/src/webui/static/tv.js index b17e7915..37155768 100644 --- a/src/webui/static/tv.js +++ b/src/webui/static/tv.js @@ -137,16 +137,15 @@ tv.ui.VideoPlayer = Ext.extend(Ext.Panel, (function() { render: { fn: function() { this.message = this.body.createChild({ - tag : 'span', + tag : 'div', cls : 'tv-video-message', - hidden: true, html: '' }); + this.message.setVisibilityMode(Ext.Element.DISPLAY); + this.message.hide(); this.video = this.body.createChild({ tag : 'video', - width : '100%', - height : '100%', html : "Your browser doesn't support html5 video" }); @@ -255,6 +254,43 @@ tv.ui.VideoPlayer = Ext.extend(Ext.Panel, (function() { this.video.dom.load(); }, + pause: function() { + this.video.dom.pause(); + }, + + setVolume: function(vol) { + this.video.dom.volume = vol / 100.0; + }, + + getVolume: function() { + return Math.round(100 * this.video.dom.volume); + }, + + setDisplaySize: function(width, height) { + this.video.setSize(width, height); + }, + + setResolution: function(res) { + this.params.resolution = res; + }, + + isIdle: function() { + return this.body.hasClass('tv-video-idle'); + }, + + fullscreen: function() { + var dom = this.video.dom; + + if(typeof dom.requestFullScreen !== 'undefined') + dom.requestFullScreen(); + + else if(typeof dom.mozRequestFullScreen !== 'undefined') + dom.mozRequestFullScreen(); + + else if(typeof dom.webkitRequestFullScreen !== 'undefined') + dom.webkitEnterFullscreen(); + }, + play: function() { this.message.hide(); this.body.removeClass('tv-video-loading'); @@ -412,6 +448,7 @@ tv.app = function() { }, renderTo: Ext.getBody() }); + videoPlayer.setDisplaySize('100%', '00%'); var chList = new tv.ui.ChannelList({ store: new Ext.data.JsonStore({