Advertisement
Guest User

AWX

a guest
Oct 13th, 2011
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  *  AWX - Ajax based Webinterface for XBMC
  3.  *  Copyright (C) 2010  MKay
  4.  *
  5.  *  This program is free software: you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation, either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program.  If not, see <http://www.gnu.org/licenses/>
  17.  */
  18.  
  19.  
  20. // TODO remove debug function
  21. function objToStr(obj, indent) {
  22.     var out = '';
  23.     for (var e in obj) {
  24.         if (typeof obj[e] == 'object') {
  25.             out += indent + e + ":\n" + objToStr(obj[e], indent+'     ') + "\n";
  26.  
  27.         } else {
  28.             out += indent + e + ": " + obj[e] + "\n";
  29.         }
  30.     }
  31.     return out;
  32. };
  33.  
  34.  
  35.  
  36. var xbmc = {};
  37.  
  38.  
  39.  
  40. (function($) {
  41.  
  42.     /* ########################### *\
  43.      |  xbmc-lib
  44.      |
  45.     \* ########################### */
  46.     $.extend(xbmc, {
  47.  
  48.         movieThumbType: 'Poster',
  49.         tvshowThumbType: 'Banner',
  50.  
  51.         xbmcHasQuit: false,
  52.         timeout: 10000,
  53.  
  54.         input: function(options) {
  55.             var settings = {
  56.                 type: 'select',
  57.                 onSuccess: null,
  58.                 onError: null
  59.             };
  60.            
  61.             $.extend(settings, options);       
  62.             var commands = {left: 1, right: 2, up: 3, down: 4, select: 7, back: 9, home: 10 };
  63.  
  64.             xbmc.httpapi(
  65.                 'action', commands[ settings.type] ,
  66.                 settings.onSuccess,
  67.                 settings.Error
  68.             );
  69.  
  70.             return true;
  71.         },
  72.         httpapi: function(command, parameter, onError, onComplete, asyncRequest) {
  73.             if (typeof asyncRequest === 'undefined')
  74.                 asyncRequest = true;
  75.  
  76.             if (!this.xbmcHasQuit) {
  77.                 $.ajax({
  78.                     async: asyncRequest,
  79.                     type: 'GET',
  80.                     url: './xbmcCmds/xbmcHttp',    
  81.                     data: {
  82.                         "command": command,
  83.                         "parameter": parameter
  84.                     },
  85.                     dataType: 'text',
  86.                     cache: false,
  87.                     timeout: this.timeout,
  88.                     success: function(result, textStatus, XMLHttpRequest) {
  89.                    
  90.                         // its possible to get here on timeouts. --> error
  91.                         if (XMLHttpRequest.readyState==4 && XMLHttpRequest.status==0) {
  92.                             if (onError) {
  93.                                 onError({"error" : { "ajaxFailed" : true, "xhr" : XMLHttpRequest, "status" : textStatus }});
  94.                             }
  95.                             return;
  96.                         }
  97.                        
  98.                         // Example Error-Response: { "error" : { "code" : -32601, "message" : "Method not found." } }
  99.                         if (result.error) {
  100.                             if (onError) { onError(result); }
  101.                             return;
  102.                         }
  103.                            
  104.                         if (onSuccess) { onSuccess(result); }
  105.                     },
  106.                     error: function(XMLHttpRequest, textStatus, errorThrown) {
  107.                         if (onError) {
  108.                             onError({"error" : { "ajaxFailed" : true, "xhr" : XMLHttpRequest, "status" : textStatus, "errorThrown" : errorThrown }});
  109.                         }
  110.                     },
  111.                     complete: function(XMLHttpRequest, textStatus) {
  112.                         if (onComplete) { onComplete(); }
  113.                     }
  114.                 });
  115.             }
  116.         },     
  117.  
  118.  
  119.         init: function(initContainer, callback) {
  120.             xbmc.periodicUpdater.start();
  121.             var timeout = parseInt(mkf.cookieSettings.get('timeout'));
  122.             this.timeout = (isNaN(timeout) || timeout < 5 || timeout > 120)? 10000: timeout*1000;
  123.             this.detectThumbTypes(initContainer, callback);
  124.         },
  125.  
  126.  
  127.  
  128.         sendCommand: function(command, onSuccess, onError, onComplete, asyncRequest) {
  129.             if (typeof asyncRequest === 'undefined')
  130.                 asyncRequest = true;
  131.  
  132.             if (!this.xbmcHasQuit) {
  133.                 $.ajax({
  134.                     async: asyncRequest,
  135.                     type: 'POST',
  136.                     url: './jsonrpc?awx',
  137.                     data: command,
  138.                     dataType: 'json',
  139.                     cache: false,
  140.                     timeout: this.timeout,
  141.                     success: function(result, textStatus, XMLHttpRequest) {
  142.  
  143.                         // its possible to get here on timeouts. --> error
  144.                         if (XMLHttpRequest.readyState==4 && XMLHttpRequest.status==0) {
  145.                             if (onError) {
  146.                                 onError({"error" : { "ajaxFailed" : true, "xhr" : XMLHttpRequest, "status" : textStatus }});
  147.                             }
  148.                             return;
  149.                         }
  150.  
  151.                         // Example Error-Response: { "error" : { "code" : -32601, "message" : "Method not found." } }
  152.                         if (result.error) {
  153.                             if (onError) { onError(result); }
  154.                             return;
  155.                         }
  156.  
  157.                         if (onSuccess) { onSuccess(result); }
  158.                     },
  159.                     error: function(XMLHttpRequest, textStatus, errorThrown) {
  160.                         if (onError) {
  161.                             onError({"error" : { "ajaxFailed" : true, "xhr" : XMLHttpRequest, "status" : textStatus, "errorThrown" : errorThrown }});
  162.                         }
  163.                     },
  164.                     complete: function(XMLHttpRequest, textStatus) {
  165.                         if (onComplete) { onComplete(); }
  166.                     }
  167.                 });
  168.             }
  169.         },
  170.  
  171.  
  172.  
  173.         getMovieThumbType: function() {
  174.             return this.movieThumbType;
  175.         },
  176.  
  177.  
  178.  
  179.         getTvShowThumbType: function() {
  180.             return this.tvshowThumbType;
  181.         },
  182.  
  183.  
  184.  
  185.         hasQuit: function() {
  186.             return this.xbmcHasQuit;
  187.         },
  188.  
  189.  
  190.  
  191.         setHasQuit: function() {
  192.             this.xbmcHasQuit = true;
  193.         },
  194.  
  195.  
  196.  
  197.         formatTime: function (seconds) {
  198.             var hh = Math.floor(seconds / 3600);
  199.             var mm = Math.floor((seconds - hh*3600) / 60);
  200.             var ss = seconds - hh*3600 - mm*60;
  201.             var result = '';
  202.             if (hh > 0)
  203.                 result = (hh<10 ? '0' : '') + hh + ':';
  204.             return  result + (mm<10 ? '0' : '') + mm + ':' + (ss<10 ? '0' : '') + ss ;
  205.         },
  206.  
  207.  
  208.  
  209.         getSeconds: function (time) {
  210.             var seconds = 0;
  211.             var i = 0;
  212.             while (time.length > 0) {
  213.                 var next = time.substr(time.length-2);
  214.                 seconds += Math.pow(60, i) * parseInt(next); // works for hours, minutes, seconds
  215.                 if (time.length > 0) {
  216.                     time = time.substr(0, time.length-3);
  217.                 }
  218.                 ++i;
  219.             }
  220.  
  221.             return seconds;
  222.         },
  223.  
  224.  
  225.  
  226.         getThumbUrl: function(url) {
  227.             return './vfs/' + encodeURI(url);
  228.         },
  229.  
  230.  
  231.  
  232.         detectThumbTypes: function(initContainer, callback) {
  233.             xbmc.sendCommand(
  234.                 //'{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "id": 1}',
  235.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": {"properties" : ["thumbnail"]}, "id": 1}',
  236.  
  237.                 function (response) {
  238.                     if (response.result.tvshows) {
  239.                         var $img = $('<img />').appendTo(initContainer);
  240.                         $.each(response.result.tvshows, function(i, tvshow) {
  241.                             if (tvshow.thumbnail) {
  242.                                 $img
  243.                                     .bind('load', function() {
  244.                                         if (this.width/this.height < 5) {
  245.                                             xbmc.tvshowThumbType = 'Poster';
  246.                                         } // else 'Banner'
  247.                                         callback();
  248.                                     })
  249.                                     .bind('error', function() {
  250.                                         // use default: 'Banner'
  251.                                         callback(mkf.lang.get('message_failed_detect_thumb_type'));
  252.                                     })
  253.                                     .attr('src', xbmc.getThumbUrl(tvshow.thumbnail));
  254.  
  255.                                 return false;
  256.                             }
  257.                         });
  258.                     } else {
  259.                         // no tv shows
  260.                         callback();
  261.                     }
  262.                 },
  263.  
  264.                 function (response) {
  265.                     callback(mkf.lang.get('message_failed_detect_thumb_type'));
  266.                 },
  267.  
  268.                 null,
  269.                 false // not async
  270.             );
  271.         },
  272.  
  273.  
  274.  
  275.         setVolume: function(options) {
  276.             var settings = {
  277.                 volume: 50,
  278.                 onSuccess: null,
  279.                 onError: null
  280.             };
  281.             $.extend(settings, options);
  282.  
  283.             xbmc.sendCommand(
  284.                 '{"jsonrpc": "2.0", "method": "XBMC.SetVolume", "params": ' + settings.volume + ', "id": 1}',
  285.                 settings.onSuccess,
  286.                 settings.onError
  287.             );
  288.         },
  289.  
  290.  
  291.  
  292.         shutdown: function(options) {
  293.             var settings = {
  294.                 type: 'shutdown',
  295.                 onSuccess: null,
  296.                 onError: null
  297.             };
  298.             $.extend(settings, options);
  299.  
  300.             var commands = {shutdown: 'System.Shutdown', quit: 'Application.Quit', suspend: 'System.Suspend', reboot: 'System.Reboot'};
  301.  
  302.             if (commands[settings.type]) {
  303.                 xbmc.sendCommand(
  304.                     '{"jsonrpc": "2.0", "method": "' + commands[settings.type] + '", "id": 1}',
  305.                     function () {
  306.                         xbmc.setHasQuit();
  307.                         settings.onSuccess();
  308.                     },
  309.                     settings.onError
  310.                 );
  311.                 return true;
  312.             }
  313.  
  314.             return false;
  315.         },
  316.  
  317.  
  318.  
  319.         control: function(options) {
  320.             var settings = {
  321.                 type: 'play',
  322.                 onSuccess: null,
  323.                 onError: null
  324.             };
  325.             $.extend(settings, options);
  326.  
  327.             var commands = {play: 'PlayPause', stop: 'Stop', prev: 'SkipPrevious', next: 'SkipNext', shuffle: 'Shuffle', unshuffle: 'Unshuffle'};
  328.  
  329.             if (commands[settings.type]) {
  330.                 xbmc.sendCommand(
  331.                     '{"jsonrpc": "2.0", "method": "Player.GetActivePlayers", "id": 1}',
  332.  
  333.                     function (response) {
  334.                         var playerResult = response.result;
  335.                         var currentPlayer = '';
  336.                         var playeridis = '';
  337.  
  338.                         if (playerResult.audio)         currentPlayer = 'Audio';
  339.                         else if (playerResult.video)    currentPlayer = 'Video';
  340.                         else if (playerResult.picture)  currentPlayer = 'Picture';
  341.                        
  342.                         if (playerResult.audio)         playeridis = 0;
  343.                         else if (playerResult.video)    playeridis = 1;
  344.                         else if (playerResult.picture)  playeridis = 2;
  345.  
  346.                         if (currentPlayer != '') {
  347.                             var tmp = (settings.type=='shuffle' || settings.type=='unshuffle'?
  348.                                         'Playlist': 'Player');
  349.                             xbmc.sendCommand(
  350.                                 //'{"jsonrpc": "2.0", "method": "' + currentPlayer + tmp + '.' + commands[settings.type] + '", "id": 1}',
  351.                                 '{"jsonrpc": "2.0", "method": "Player.' + commands[settings.type] + '", "params": { "playerid": ' + playeridis + ' }, "id": 1}',
  352.                                 settings.onSuccess,
  353.                                 settings.onError
  354.                             );
  355.                         }
  356.                     },
  357.                     settings.onError
  358.                 );
  359.                 return true;
  360.             }
  361.             return false;
  362.         },
  363.  
  364.  
  365.  
  366.         seekPercentage: function(options) {
  367.             var settings = {
  368.                 percentage: 0,
  369.                 onSuccess: null,
  370.                 onError: null
  371.             };
  372.             $.extend(settings, options);
  373.  
  374.             xbmc.sendCommand(
  375.                 '{"jsonrpc": "2.0", "method": "Player.GetActivePlayers", "id": 1}',
  376.  
  377.                 function (response) {
  378.                     var playerResult = response.result;
  379.                     var player = '';
  380.  
  381.                     if (playerResult.audio) {
  382.                         player = 'Audio';
  383.  
  384.                     } else if (playerResult.video) {
  385.                         player = 'Video';
  386.  
  387.                     } else {
  388.                         // No player is active
  389.                         return;
  390.                     }
  391.  
  392.                     xbmc.sendCommand(
  393.                         '{"jsonrpc": "2.0", "method": "' + player + 'Player.SeekPercentage", "params": ' + settings.percentage + ', "id": 1}',
  394.  
  395.                         settings.onSuccess,
  396.                         settings.onError
  397.                     );
  398.                 },
  399.  
  400.                 settings.onError
  401.             );
  402.         },
  403.  
  404.  
  405.  
  406.         getArtists: function(options) {
  407.             var settings = {
  408.                 onSuccess: null,
  409.                 onError: null
  410.             };
  411.             $.extend(settings, options);
  412.  
  413.             xbmc.sendCommand(
  414.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetArtists", "params": {"sort": { "order": "ascending", "method": "artist" } }, "id": 1}',
  415.  
  416.                 function(response) {
  417.                     settings.onSuccess(response.result);
  418.                 },
  419.  
  420.                 settings.onError
  421.             );
  422.         },
  423.  
  424.  
  425.  
  426.         getArtistsAlbums: function(options) {
  427.             var settings = {
  428.                 artistid: 0,
  429.                 onSuccess: null,
  430.                 onError: null
  431.             };
  432.             $.extend(settings, options);
  433.  
  434.             xbmc.sendCommand(
  435.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "artistid" : ' + settings.artistid + ', "properties": ["artist", "genre", "rating", "thumbnail"] }, "id": 1}',
  436.  
  437.                 function(response) {
  438.                     settings.onSuccess(response.result);
  439.                 },
  440.  
  441.                 settings.onError
  442.             );
  443.         },
  444.  
  445.  
  446.  
  447.         getAlbums: function(options) {
  448.             var settings = {
  449.                 onSuccess: null,
  450.                 onError: null
  451.             };
  452.             $.extend(settings, options);
  453.  
  454.             var order = mkf.cookieSettings.get('albumOrder')=='album'? 'label' : 'artist';
  455.  
  456.             xbmc.sendCommand(
  457.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": {"properties": ["artist", "genre", "rating", "thumbnail"], "sort": { "order": "ascending", "method": "' + order + '" } }, "id": 1}',
  458.  
  459.                 function(response) {
  460.                     settings.onSuccess(response.result);
  461.                 },
  462.  
  463.                 settings.onError
  464.             );
  465.         },
  466.  
  467.  
  468.  
  469.         addSongToPlaylist: function(options) {
  470.             var settings = {
  471.                 songid: 0,
  472.                 onSuccess: null,
  473.                 onError: null,
  474.                 async: true
  475.             };
  476.             $.extend(settings, options);
  477.  
  478.             xbmc.sendCommand(
  479.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": {"item": {"songid": ' + settings.songid + '}, "playlistid": 0}, "id": 1}',
  480.                 settings.onSuccess,
  481.                 settings.onError,
  482.                 null,
  483.                 settings.async
  484.             );
  485.         },
  486.  
  487.  
  488.  
  489.         addAudioFileToPlaylist: function(options) {
  490.             var settings = {
  491.                 file: '',
  492.                 onSuccess: null,
  493.                 onError: null,
  494.                 async: true
  495.             };
  496.             $.extend(settings, options);
  497.  
  498.             xbmc.sendCommand(
  499.                 //'{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "item": {"file": "' + settings.file.replace(/\\/g, "\\\\") + '"} }, "id": 1}',
  500.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "item": {"file": "' + settings.file.replace(/\\/g, "\\\\") + '"}, "playlistid": 0 }, "id": 1}',
  501.                 settings.onSuccess,
  502.                 settings.onError,
  503.                 null,
  504.                 settings.async
  505.             );
  506.         },
  507.  
  508.  
  509.  
  510.         addAudioFolderToPlaylist: function(options) {
  511.             var settings = {
  512.                 folder: '',
  513.                 onSuccess: null,
  514.                 onError: null
  515.             };
  516.             $.extend(settings, options);
  517.  
  518.             xbmc.getDirectory({
  519.                 media: 'Audio',
  520.                 directory: settings.folder.replace(/\\/g, "\\\\"),
  521.  
  522.                 onSuccess: function(result) {
  523.                     var error = false;
  524.                     var files = result.files;
  525.                     if (files) {
  526.                         files.sort(function(a, b) {
  527.                             if (a.file < b.file) return -1;
  528.                             if (a.file > b.file) return 1;
  529.                             return 0;
  530.                         });
  531.                         $.each(files, function(i, file)  {
  532.                             xbmc.addAudioFileToPlaylist({
  533.                                 'file': file.file,
  534.                                 onError: function() {
  535.                                     error = true;
  536.                                 },
  537.                                 async: false
  538.                             });
  539.                         });
  540.                     }
  541.                     if (error) {
  542.                         settings.onError(mkf.lang.get('message_failed_add_files_to_playlist'));
  543.                     } else {
  544.                         settings.onSuccess();
  545.                     }
  546.                 },
  547.  
  548.                 onError: function() {
  549.                     settings.onError(mkf.lang.get('message_failed_folders_content'));
  550.                 }
  551.             });
  552.         },
  553.  
  554.  
  555.  
  556.         addAlbumToPlaylist: function(options) {
  557.             var settings = {
  558.                 albumid: 0,
  559.                 onSuccess: null,
  560.                 onError: null
  561.             };
  562.             $.extend(settings, options);
  563.  
  564.             // Comparator to sort albums by tracknumber ASC
  565.             var songComparator = function(a, b) {
  566.                 return a.tracknumber - b.tracknumber;
  567.             }
  568.  
  569.             xbmc.sendCommand(
  570.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": {"albumid": ' + settings.albumid + ', "properties": ["track"]}, "id": 1}',
  571.  
  572.                 function(response) {
  573.                     if (!response.result || !response.result.songs) {
  574.                         settings.onError(mkf.lang.get('message_album_not_found'));
  575.                         return;
  576.                     }
  577.  
  578.                     var songs = response.result.songs;
  579.                     songs.sort(songComparator); // sort by tracknumber ASC
  580.                     var errors = 0;
  581.  
  582.                     // add each song of the album to the playlist
  583.                     $.each(songs, function(i, song)  {
  584.                         // add Song to playlist ... max. 2 retries if add failed
  585.                         xbmc.addSongToPlaylist({songid: song.songid, async: false, onError: function() {
  586.                             xbmc.addSongToPlaylist({songid: song.songid, async: false, onError: function() {
  587.                                 xbmc.addSongToPlaylist({songid: song.songid, async: false, onError: function() {
  588.                                     errors += 1;
  589.                                 }});
  590.                             }});
  591.                         }});
  592.                     });
  593.  
  594.                     if (errors != 0) {
  595.                         settings.onError(mkf.lang.get('message_failed_add_songs_to_playlist', [errors]));
  596.                     } else {
  597.                         settings.onSuccess();
  598.                     }
  599.                 },
  600.  
  601.                 function(response) {
  602.                     settings.onError(mkf.lang.get('message_failed_albums_songs'));
  603.                 }
  604.             );
  605.         },
  606.  
  607.  
  608.  
  609.         clearAudioPlaylist: function(options) {
  610.             var settings = {
  611.                 onSuccess: null,
  612.                 onError: null,
  613.             };
  614.             $.extend(settings, options);
  615.  
  616.             xbmc.sendCommand(
  617.                 '{"jsonrpc": "2.0", "method": "Playlist.Clear", "params": { "playlistid": 0 }, "id": 1}',
  618.                 settings.onSuccess,
  619.                 settings.onError
  620.             );
  621.         },
  622.  
  623.  
  624.  
  625.         playAudio: function(options) {
  626.             var settings = {
  627.                 item: 0,
  628.                 onSuccess: null,
  629.                 onError: null,
  630.             };
  631.             $.extend(settings, options);
  632.  
  633.             xbmc.sendCommand(
  634.                 // '{"jsonrpc": "2.0", "method": "Player.Open", "params": {"item": ' + settings.item + '}, "id": 1}',
  635.                 '{"jsonrpc": "2.0", "method": "Player.Open", "params" : { "item" : { "playlistid" : 0, "position": ' + settings.item + ' } }, "id": 1}',
  636.                 settings.onSuccess,
  637.                 function(response) {
  638.                     settings.onError(mkf.lang.get('message_failed_play' + 'settings.item'));
  639.                 }
  640.             );
  641.         },
  642.  
  643.  
  644.  
  645.         playAlbum: function(options) {
  646.             var settings = {
  647.                 albumid: 0,
  648.                 onSuccess: null,
  649.                 onError: null,
  650.             };
  651.             $.extend(settings, options);
  652.  
  653.             this.clearAudioPlaylist({
  654.                 onSuccess: function() {
  655.                     xbmc.addAlbumToPlaylist({
  656.                         albumid: settings.albumid,
  657.  
  658.                         onSuccess: function() {
  659.                             xbmc.playAudio({
  660.                                 onSuccess: settings.onSuccess,
  661.                                 onError: function(errorText) {
  662.                                     settings.onError(errorText);
  663.                                 }
  664.                             });
  665.                         },
  666.  
  667.                         onError: function(errorText) {
  668.                             settings.onError(errorText);
  669.                         }
  670.                     });
  671.                 },
  672.  
  673.                 onError: function() {
  674.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  675.                 }
  676.             });
  677.         },
  678.  
  679.  
  680.  
  681.         playSong: function(options) {
  682.             var settings = {
  683.                 songid: 0,
  684.                 onSuccess: null,
  685.                 onError: null,
  686.             };
  687.             $.extend(settings, options);
  688.  
  689.             this.clearAudioPlaylist({
  690.                 onSuccess: function() {
  691.                     xbmc.addSongToPlaylist({
  692.                         songid: settings.songid,
  693.  
  694.                         onSuccess: function() {
  695.                             xbmc.playAudio({
  696.                                 onSuccess: settings.onSuccess,
  697.                                 onError: function(errorText) {
  698.                                     settings.onError(errorText);
  699.                                 }
  700.                             });
  701.                         },
  702.  
  703.                         onError: function() {
  704.                             settings.onError(mkf.lang.get('message_failed_add_song_to_playlist'));
  705.                         }
  706.                     });
  707.                 },
  708.  
  709.                 onError: function() {
  710.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  711.                 }
  712.             });
  713.         },
  714.  
  715.  
  716.  
  717.         playAudioFile: function(options) {
  718.             var settings = {
  719.                 file: '',
  720.                 onSuccess: null,
  721.                 onError: null,
  722.             };
  723.             $.extend(settings, options);
  724.  
  725.             this.clearAudioPlaylist({
  726.                 onSuccess: function() {
  727.                     xbmc.addAudioFileToPlaylist({
  728.                         file: settings.file,
  729.  
  730.                         onSuccess: function() {
  731.                             xbmc.playAudio({
  732.                                 onSuccess: settings.onSuccess,
  733.                                 onError: function(errorText) {
  734.                                     settings.onError(errorText);
  735.                                 }
  736.                             });
  737.                         },
  738.  
  739.                         onError: function() {
  740.                             settings.onError(mkf.lang.get('message_failed_add_file_to_playlist'));
  741.                         }
  742.                     });
  743.                 },
  744.  
  745.                 onError: function() {
  746.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  747.                 }
  748.             });
  749.         },
  750.  
  751.  
  752.  
  753.         playAudioFolder: function(options) {
  754.             var settings = {
  755.                 folder: '',
  756.                 onSuccess: null,
  757.                 onError: null,
  758.             };
  759.             $.extend(settings, options);
  760.  
  761.             this.clearAudioPlaylist({
  762.                 onSuccess: function() {
  763.                     xbmc.addAudioFolderToPlaylist({
  764.                         folder: settings.folder,
  765.  
  766.                         onSuccess: function() {
  767.                             xbmc.playAudio({
  768.                                 onSuccess: settings.onSuccess,
  769.                                 onError: function(errorText) {
  770.                                     settings.onError(errorText);
  771.                                 }
  772.                             });
  773.                         },
  774.  
  775.                         onError: function(errorText) {
  776.                             settings.onError(errorText);
  777.                         }
  778.                     });
  779.                 },
  780.  
  781.                 onError: function() {
  782.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  783.                 }
  784.             });
  785.         },
  786.  
  787.  
  788.  
  789.         getAlbumsSongs: function(options) {
  790.             var settings = {
  791.                 albumid: 0,
  792.                 onSuccess: null,
  793.                 onError: null,
  794.             };
  795.             $.extend(settings, options);
  796.  
  797.             xbmc.sendCommand(
  798.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": { "albumid": ' + settings.albumid + ', "properties": ["artist", "track"] }, "id": 1}',
  799.  
  800.                 function(response) {
  801.                     settings.onSuccess(response.result);
  802.                 },
  803.  
  804.                 settings.onError
  805.             );
  806.         },
  807.  
  808.  
  809.  
  810.         getAudioPlaylist: function(options) {
  811.             var settings = {
  812.                 onSuccess: null,
  813.                 onError: null,
  814.             };
  815.             $.extend(settings, options);
  816.  
  817.             xbmc.sendCommand(
  818.                 '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "properties": ["title", "album", "artist", "duration"], "playlistid": 0 }, "id": 1}',
  819.  
  820.                 function(response) {
  821.                     settings.onSuccess(response.result);
  822.                 },
  823.  
  824.                 settings.onError
  825.             );
  826.         },
  827.  
  828.  
  829.  
  830.         clearVideoPlaylist: function(options) {
  831.             var settings = {
  832.                 onSuccess: null,
  833.                 onError: null,
  834.             };
  835.             $.extend(settings, options);
  836.  
  837.             xbmc.sendCommand(
  838.                 '{"jsonrpc": "2.0", "method": "Playlist.Clear", "params": { "playlistid": 1 }, "id": 1}',
  839.                 settings.onSuccess,
  840.                 settings.onError
  841.             );
  842.         },
  843.  
  844.  
  845.  
  846.         playVideo: function(options) {
  847.             var settings = {
  848.                 item: 0,
  849.                 onSuccess: null,
  850.                 onError: null,
  851.             };
  852.             $.extend(settings, options);
  853.  
  854.             xbmc.sendCommand(
  855.                 // '{"jsonrpc": "2.0", "method": "Player.Open", "params": {"item": ' + settings.item + '}, "id": 1}',
  856.                 '{"jsonrpc": "2.0", "method": "Player.Open", "params" : { "item" : { "playlistid" : 1, "position": ' + settings.item + ' } }, "id": 1}',
  857.                 settings.onSuccess,
  858.                 function(response) {
  859.                     settings.onError(mkf.lang.get('message_failed_play'));
  860.                 }
  861.             );
  862.         },
  863.  
  864.  
  865.  
  866.         addVideoFileToPlaylist: function(options) {
  867.             var settings = {
  868.                 file: '',
  869.                 onSuccess: null,
  870.                 onError: null,
  871.                 async: true
  872.             };
  873.             $.extend(settings, options);
  874.  
  875.             xbmc.sendCommand(
  876.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "file": "' + settings.file.replace(/\\/g, "\\\\") + '", "playlistid": 1 }, "id": 1}',
  877.                 settings.onSuccess,
  878.                 settings.onError,
  879.                 null,
  880.                 settings.async
  881.             );
  882.         },
  883.  
  884.  
  885.  
  886.         addVideoFolderToPlaylist: function(options) {
  887.             var settings = {
  888.                 folder: '',
  889.                 onSuccess: null,
  890.                 onError: null
  891.             };
  892.             $.extend(settings, options);
  893.  
  894.  
  895.             xbmc.getDirectory({
  896.                 media: 'Video',
  897.                 directory: settings.folder.replace(/\\/g, "\\\\"),
  898.  
  899.                 onSuccess: function(result) {
  900.                     var error = false;
  901.                     var files = result.files;
  902.                     if (files) {
  903.                         files.sort(function(a, b) {
  904.                             if (a.file < b.file) return -1;
  905.                             if (a.file > b.file) return 1;
  906.                             return 0;
  907.                         });
  908.                         alert(objToStr(files,''));
  909.                         $.each(files, function(i, file)  {
  910.                             xbmc.addVideoFileToPlaylist({
  911.                                 'file': file.file,
  912.                                 onError: function() {
  913.                                     error = true;
  914.                                 },
  915.                                 async: false
  916.                             });
  917.                         });
  918.                     }
  919.                     if (error) {
  920.                         settings.onError(mkf.lang.get('message_failed_add_files_to_playlist'));
  921.                     } else {
  922.                         settings.onSuccess();
  923.                     }
  924.                 },
  925.  
  926.                 onError: function() {
  927.                     settings.onError(mkf.lang.get('message_failed_folders_content'));
  928.                 }
  929.             });
  930.         },
  931.  
  932.  
  933.  
  934.         addMovieToPlaylist: function(options) {
  935.             var settings = {
  936.                 movieid: 0,
  937.                 onSuccess: null,
  938.                 onError: null,
  939.             };
  940.             $.extend(settings, options);
  941.         /*
  942.             function myobject(){
  943.             this.movieid = 0;
  944.             }
  945.             var args = new myobject();
  946.             args.movieid = settings.movieid;
  947.         */
  948.             xbmc.sendCommand(
  949.                 //'{"jsonrpc": "2.0", "method": "VideoPlaylist.Add", "params": {"movieid": ' + settings.movieid + '}, "id": 1}',
  950.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": {"item": {"movieid": ' + settings.movieid + '}, "playlistid": 1}, "id": 1}',
  951.                 settings.onSuccess,
  952.                 settings.onError,
  953.                 null,
  954.                 settings.async
  955.             );
  956.         },
  957.  
  958.  
  959.  
  960.         playMovie: function(options) {
  961.             var settings = {
  962.                 movieid: 0,
  963.                 onSuccess: null,
  964.                 onError: null,
  965.             };
  966.             $.extend(settings, options);
  967.  
  968.             this.clearVideoPlaylist({
  969.                 onSuccess: function() {
  970.                     xbmc.addMovieToPlaylist({
  971.                         movieid: settings.movieid,
  972.  
  973.                         onSuccess: function() {
  974.                             xbmc.playVideo({
  975.                                 onSuccess: settings.onSuccess,
  976.                                 onError: function(errorText) {
  977.                                     settings.onError(errorText);
  978.                                 }
  979.                             });
  980.                         },
  981.  
  982.                         onError: function() {
  983.                             settings.onError(mkf.lang.get('message_failed_add_movie_to_playlist'));
  984.                         }
  985.                     });
  986.                 },
  987.  
  988.                 onError: function() {
  989.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  990.                 }
  991.             });
  992.         },
  993.  
  994.  
  995.  
  996.         playVideoFile: function(options) {
  997.             var settings = {
  998.                 file: '',
  999.                 onSuccess: null,
  1000.                 onError: null,
  1001.             };
  1002.             $.extend(settings, options);
  1003.  
  1004.             this.clearVideoPlaylist({
  1005.                 onSuccess: function() {
  1006.                     xbmc.addVideoFileToPlaylist({
  1007.                         file: settings.file,
  1008.  
  1009.                         onSuccess: function() {
  1010.                             xbmc.playVideo({
  1011.                                 onSuccess: settings.onSuccess,
  1012.                                 onError: function(errorText) {
  1013.                                     settings.onError(errorText);
  1014.                                 }
  1015.                             });
  1016.                         },
  1017.  
  1018.                         onError: function() {
  1019.                             settings.onError(mkf.lang.get('message_failed_add_file_to_playlist'));
  1020.                         }
  1021.                     });
  1022.                 },
  1023.  
  1024.                 onError: function() {
  1025.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  1026.                 }
  1027.             });
  1028.         },
  1029.  
  1030.  
  1031.  
  1032.         playVideoFolder: function(options) {
  1033.             var settings = {
  1034.                 folder: '',
  1035.                 onSuccess: null,
  1036.                 onError: null,
  1037.             };
  1038.             $.extend(settings, options);
  1039.  
  1040.             this.clearVideoPlaylist({
  1041.                 onSuccess: function() {
  1042.                     xbmc.addVideoFolderToPlaylist({
  1043.                         folder: settings.folder,
  1044.  
  1045.                         onSuccess: function() {
  1046.                             xbmc.playVideo({
  1047.                                 onSuccess: settings.onSuccess,
  1048.                                 onError: function(errorText) {
  1049.                                     settings.onError(errorText);
  1050.                                 }
  1051.                             });
  1052.                         },
  1053.  
  1054.                         onError: function(errorText) {
  1055.                             settings.onError(errorText);
  1056.                         }
  1057.                     });
  1058.                 },
  1059.  
  1060.                 onError: function() {
  1061.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  1062.                 }
  1063.             });
  1064.         },
  1065.  
  1066.  
  1067.  
  1068.         /*getMovieInfo: function(options) {
  1069.             var settings = {
  1070.                 movieid: 0,
  1071.                 onSuccess: null,
  1072.                 onError: null,
  1073.             };
  1074.             $.extend(settings, options);
  1075.  
  1076.             // TODO better: do not get all movies
  1077.             xbmc.sendCommand(
  1078.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "properties" : ["genre", "director", "plot", "title", "originaltitle", "runtime", "year", "rating"] }, "id": 1}',
  1079.  
  1080.                 function (response) {
  1081.                     var movies = response.result.movies;
  1082.                     var result = null;
  1083.  
  1084.                     if (response.result.total > 0) {
  1085.                         $.each(movies, function(i, movie)  {
  1086.                             if (movie.movieid == settings.movieid) {
  1087.                                 result = movie;
  1088.                                 return false;
  1089.                             }
  1090.                         });
  1091.                     }
  1092.  
  1093.                     settings.onSuccess(result);
  1094.                 },
  1095.  
  1096.                 settings.onError
  1097.             );
  1098.         },*/
  1099.  
  1100.  
  1101.  
  1102.         getMovies: function(options) {
  1103.             var settings = {
  1104.                 onSuccess: null,
  1105.                 onError: null,
  1106.             };
  1107.             $.extend(settings, options);
  1108.  
  1109.             xbmc.sendCommand(
  1110.                 //'{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "start": 0, "properties" : ["genre", "director", "plot", "title", "originaltitle", "runtime", "year", "rating"], "sort": { "order": "ascending", "method": "label" } }, "id": 1}',
  1111.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties" : ["genre", "director", "plot", "title", "originaltitle", "runtime", "year", "rating", "thumbnail"], "sort": { "order": "ascending", "method": "label" } }, "id": 1}',
  1112.                 function(response) {
  1113.                     settings.onSuccess(response.result);
  1114.                 },
  1115.                 settings.onError
  1116.             );
  1117.         },
  1118.  
  1119.  
  1120.  
  1121.         addEpisodeToPlaylist: function(options) {
  1122.             var settings = {
  1123.                 episodeid: 0,
  1124.                 onSuccess: null,
  1125.                 onError: null,
  1126.             };
  1127.             $.extend(settings, options);
  1128.  
  1129.             xbmc.sendCommand(
  1130.                 //'{"jsonrpc": "2.0", "method": "VideoPlaylist.Add", "params": {"episodeid": ' + settings.episodeid + '}, "id": 1}',
  1131.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": {"item": {"episodeid": ' + settings.episodeid + '}, "playlistid": 1}, "id": 1}',
  1132.                 settings.onSuccess,
  1133.                 settings.onError,
  1134.                 null,
  1135.                 settings.async
  1136.             );
  1137.         },
  1138.  
  1139.  
  1140.  
  1141.         playEpisode: function(options) {
  1142.             var settings = {
  1143.                 episodeid: 0,
  1144.                 onSuccess: null,
  1145.                 onError: null,
  1146.             };
  1147.             $.extend(settings, options);
  1148.  
  1149.             this.clearVideoPlaylist({
  1150.                 onSuccess: function() {
  1151.                     xbmc.addEpisodeToPlaylist({
  1152.                         episodeid: settings.episodeid,
  1153.  
  1154.                         onSuccess: function() {
  1155.                             xbmc.playVideo({
  1156.                                 onSuccess: settings.onSuccess,
  1157.                                 onError: function(errorText) {
  1158.                                     settings.onError(errorText);
  1159.                                 }
  1160.                             });
  1161.                         },
  1162.  
  1163.                         onError: function() {
  1164.                             settings.onError(mkf.lang.get('message_failed_add_episode_to_playlist'));
  1165.                         }
  1166.                     });
  1167.                 },
  1168.  
  1169.                 onError: function() {
  1170.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  1171.                 }
  1172.             });
  1173.         },
  1174.  
  1175.  
  1176.  
  1177.         getTvShows: function(options) {
  1178.             var settings = {
  1179.                 onSuccess: null,
  1180.                 onError: null,
  1181.             };
  1182.             $.extend(settings, options);
  1183.  
  1184.             xbmc.sendCommand(
  1185.                 //'{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "start": 0, "properties": ["genre", "director", "plot", "title", "originaltitle", "runtime", "year", "rating"] }, "id": 1}',
  1186.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": ["genre", "plot", "title", "originaltitle", "year", "rating", "thumbnail"] }, "id": 1}',
  1187.                 function(response) {
  1188.                     settings.onSuccess(response.result);
  1189.                 },
  1190.                 settings.onError
  1191.             );
  1192.         },
  1193.  
  1194.  
  1195.  
  1196.         getSeasons: function(options) {
  1197.             var settings = {
  1198.                 tvshowid: 0,
  1199.                 onSuccess: null,
  1200.                 onError: null,
  1201.             };
  1202.             $.extend(settings, options);
  1203.  
  1204.             xbmc.sendCommand(
  1205.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetSeasons", "params": { "tvshowid": ' + settings.tvshowid + ', "properties": ["season"]}, "id": 1}',
  1206.                 function(response) {
  1207.                     settings.onSuccess(response.result);
  1208.                 },
  1209.                 settings.onError
  1210.             );
  1211.         },
  1212.  
  1213.  
  1214.  
  1215.         getEpisodes: function(options) {
  1216.             var settings = {
  1217.                 tvshowid: 0,
  1218.                 season: 0,
  1219.                 onSuccess: null,
  1220.                 onError: null,
  1221.             };
  1222.             $.extend(settings, options);
  1223.  
  1224.             xbmc.sendCommand(
  1225.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "tvshowid": ' + settings.tvshowid + ', "season" : ' + settings.season + ', "properties": ["episode"], "sort": { "order": "ascending", "method": "episode" } }, "id": 1}',
  1226.                 function(response) {
  1227.                     settings.onSuccess(response.result);
  1228.                 },
  1229.                 settings.onError
  1230.             );
  1231.         },
  1232.  
  1233.  
  1234.  
  1235.         getVideoPlaylist: function(options) {
  1236.             var settings = {
  1237.                 onSuccess: null,
  1238.                 onError: null,
  1239.             };
  1240.             $.extend(settings, options);
  1241.  
  1242.             xbmc.sendCommand(
  1243.                 '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "playlistid": 1}, "id": 1}',
  1244.  
  1245.                 function(response) {
  1246.                     settings.onSuccess(response.result);
  1247.                 },
  1248.  
  1249.                 settings.onError
  1250.             );
  1251.         },
  1252.  
  1253.  
  1254.  
  1255.         getSources: function(options) {
  1256.             var settings = {
  1257.                 media: 'Audio',
  1258.                 onSuccess: null,
  1259.                 onError: null,
  1260.                 async: true
  1261.             };
  1262.             $.extend(settings, options);
  1263.  
  1264.             xbmc.sendCommand(
  1265.                 '{"jsonrpc": "2.0", "method": "Files.GetSources", "params" : { "media" : "' + (settings.media=='Audio'? 'music' : 'video') + '" }, "id": 1}',
  1266.  
  1267.                 function(response) {
  1268.                     settings.onSuccess(response.result);
  1269.                 },
  1270.  
  1271.                 settings.onError,
  1272.                 null,
  1273.                 settings.async
  1274.             );
  1275.         },
  1276.  
  1277.  
  1278.  
  1279.         getDirectory: function(options) {
  1280.             var settings = {
  1281.                 media: 'Audio',
  1282.                 directory: '',
  1283.                 onSuccess: null,
  1284.                 onError: null,
  1285.                 async: true
  1286.             };
  1287.             $.extend(settings, options);
  1288.  
  1289.             xbmc.sendCommand(
  1290.                 '{"jsonrpc": "2.0", "method": "Files.GetDirectory", "params" : { "directory" : "' + settings.directory.replace(/\\/g, "\\\\") + '", "media" : "' + (settings.media=='Audio'? 'music' : 'video') +'", "sort": { "order": "ascending", "method": "file" } }, "id": 1}',
  1291.  
  1292.                 function(response) {
  1293.                     settings.onSuccess(response.result);
  1294.                 },
  1295.  
  1296.                 settings.onError,
  1297.                 null,
  1298.                 settings.async
  1299.             );
  1300.         }
  1301.  
  1302.  
  1303.  
  1304.     }); // END xbmc
  1305.  
  1306.  
  1307.  
  1308.     $.extend(xbmc, {
  1309.         periodicUpdater: {
  1310.             volumeChangedListener: [],
  1311.             currentlyPlayingChangedListener: [],
  1312.             playerStatusChangedListener: [],
  1313.             progressChangedListener: [],
  1314.  
  1315.             lastVolume: -1,
  1316.             currentlyPlayingFile: null,
  1317.             progress: '',
  1318.             playerStatus: 'stopped',
  1319.             shuffleStatus: false,
  1320.  
  1321.             addVolumeChangedListener: function(fn) {
  1322.                 this.volumeChangedListener.push(fn);
  1323.             },
  1324.  
  1325.             addCurrentlyPlayingChangedListener: function(fn) {
  1326.                 this.currentlyPlayingChangedListener.push(fn);
  1327.             },
  1328.  
  1329.             addPlayerStatusChangedListener: function(fn) {
  1330.                 this.playerStatusChangedListener.push(fn);
  1331.             },
  1332.  
  1333.             addProgressChangedListener: function(fn) {
  1334.                 this.progressChangedListener.push(fn);
  1335.             },
  1336.  
  1337.             firePlayerStatusChanged: function(status) {
  1338.                 $.each(xbmc.periodicUpdater.playerStatusChangedListener, function(i, listener)  {
  1339.                     listener(status);
  1340.                 });
  1341.             },
  1342.  
  1343.             fireCurrentlyPlayingChanged: function(file) {
  1344.                 $.each(xbmc.periodicUpdater.currentlyPlayingChangedListener, function(i, listener)  {
  1345.                     listener(file);
  1346.                 });
  1347.             },
  1348.  
  1349.             fireProgressChanged: function(progress) {
  1350.                 $.each(xbmc.periodicUpdater.progressChangedListener, function(i, listener)  {
  1351.                     listener(progress);
  1352.                 });
  1353.             },
  1354.  
  1355.             start: function() {
  1356.                 setTimeout($.proxy(this, "periodicStep"), 10);
  1357.             },
  1358.  
  1359.             periodicStep: function() {
  1360.  
  1361.                 var curPlayData = {};
  1362.                 var shuffle = false;
  1363.                 var time = '';
  1364.                 var file = '';
  1365.                 var volume = 0;
  1366.  
  1367.                 // ---------------------------------
  1368.                 // ---      Volume Changes       ---
  1369.                 // ---------------------------------
  1370.                 // --- Currently Playing Changes ---
  1371.                 // ---------------------------------
  1372.                 if ((this.volumeChangedListener &&
  1373.                     this.volumeChangedListener.length) ||
  1374.                     (this.currentlyPlayingChangedListener &&
  1375.                     this.currentlyPlayingChangedListener.length) ||
  1376.                     (this.playerStatusChangedListener &&
  1377.                     this.playerStatusChangedListener.length) ||
  1378.                     (this.progressChangedListener &&
  1379.                     this.progressChangedListener.length)) {
  1380.  
  1381.                     var activePlayer = '';
  1382.  
  1383.                     xbmc.sendCommand(
  1384.                         '{"jsonrpc": "2.0", "method": "XBMC.GetInfoLabels", "params" : {"labels": ["MusicPlayer.Title", "MusicPlayer.Album", "MusicPlayer.Artist", "Player.Time", "Player.Duration", "Player.Volume", "Playlist.Random", "VideoPlayer.Title", "VideoPlayer.TVShowTitle", "Player.Filenameandpath"]}, "id": 1}',
  1385.  
  1386.                         function (response) {
  1387.                             var infoResult = response.result;
  1388.  
  1389.                             shuffle = (infoResult['Playlist.Random']=="Random"? true: false);
  1390.                             time = infoResult['Player.Time'];
  1391.                             file = infoResult['Player.Filenameandpath'];
  1392.  
  1393.                             var tmp = parseFloat(infoResult['Player.Volume']);
  1394.                             volume = (isNaN(tmp)? 0: (tmp+60)/60*100); // -60 dB to 0 dB (--> 0% to 100%)
  1395.  
  1396.                             curPlayData.duration = infoResult['Player.Duration'];
  1397.                             curPlayData.file = infoResult['Player.Filenameandpath'];
  1398.  
  1399.                             if (infoResult['MusicPlayer.Title'] != "") {
  1400.                                 activePlayer = 'audio';
  1401.                                 curPlayData.title = infoResult['MusicPlayer.Title'];
  1402.                                 curPlayData.album = infoResult['MusicPlayer.Album'];
  1403.                                 curPlayData.artist = infoResult['MusicPlayer.Artist'];
  1404.  
  1405.                             } else if (infoResult['VideoPlayer.Title'] != "") {
  1406.                                 activePlayer = 'video';
  1407.                                 curPlayData.title = infoResult['VideoPlayer.Title'];
  1408.                                 curPlayData.showtitle = infoResult['VideoPlayer.TVShowTitle'];
  1409.  
  1410.                             } else {
  1411.                                 activePlayer = 'none';
  1412.                             }
  1413.                         },
  1414.  
  1415.                         function(response) {
  1416.                             activePlayer = 'none'; // ERROR
  1417.                         },
  1418.  
  1419.                         null, false // not async
  1420.                     );
  1421.  
  1422.                     // has volume changed?
  1423.                     if (volume != xbmc.periodicUpdater.lastVolume) {
  1424.                         $.each(xbmc.periodicUpdater.volumeChangedListener, function(i, listener)  {
  1425.                             listener(volume);
  1426.                         });
  1427.                     }
  1428.  
  1429.                     if (activePlayer == 'none' &&
  1430.                         this.playerStatus != 'stopped') {
  1431.  
  1432.                         this.playerStatus = 'stopped';
  1433.                         this.firePlayerStatusChanged('stopped');
  1434.                     }
  1435.  
  1436.                     // shuffle status changed?
  1437.                     if (this.shuffleStatus != shuffle) {
  1438.                         this.shuffleStatus = shuffle;
  1439.                         this.firePlayerStatusChanged(shuffle? 'shuffleOn': 'shuffleOff');
  1440.                     }
  1441.  
  1442.                     // is playing
  1443.                     if (activePlayer != 'none') {
  1444.                         var request = '';
  1445.  
  1446.                         if (activePlayer == 'audio') {
  1447.                             request = '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "properties": ["title", "album", "artist", "duration"], "playlistid": 0 }, "id": 1}';
  1448.  
  1449.                         } else if (activePlayer == 'video') {
  1450.                             request = '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "properties": ["title", "season", "episode", "duration", "showtitle"], "playlistid": 1 }, "id": 1}';
  1451.                         }
  1452.  
  1453.                         xbmc.sendCommand(
  1454.                             request,
  1455.  
  1456.                             function (response) {
  1457.                                 var currentPlayer = response.result;
  1458.                                 var currentItem;
  1459.  
  1460.                                 // playlist may be cleared. Use data retrieved by GetInfoLabels
  1461.                                 if (!currentPlayer.items || !currentPlayer.items[currentPlayer.current]) {
  1462.                                     currentItem = curPlayData;
  1463.  
  1464.                                 } else {
  1465.                                     currentItem = currentPlayer.items[currentPlayer.current];
  1466.                                     $.extend(currentItem, curPlayData);
  1467.                                 }
  1468.  
  1469.  
  1470.                                 if (!currentPlayer.playing) {
  1471.                                     // not playing
  1472.                                     if (xbmc.periodicUpdater.playerStatus != 'stopped') {
  1473.                                         xbmc.periodicUpdater.playerStatus = 'stopped';
  1474.                                         xbmc.periodicUpdater.firePlayerStatusChanged('stopped');
  1475.                                     }
  1476.  
  1477.                                 } else if (currentPlayer.paused && xbmc.periodicUpdater.playerStatus != 'paused') {
  1478.                                     xbmc.periodicUpdater.playerStatus = 'paused';
  1479.                                     xbmc.periodicUpdater.firePlayerStatusChanged('paused');
  1480.  
  1481.                                 } else if (!currentPlayer.paused && xbmc.periodicUpdater.playerStatus != 'playing') {
  1482.                                     xbmc.periodicUpdater.playerStatus = 'playing';
  1483.                                     xbmc.periodicUpdater.firePlayerStatusChanged('playing');
  1484.                                 }
  1485.  
  1486.                                 // has current file changed?
  1487.                                 if (xbmc.periodicUpdater.currentlyPlayingFile != currentItem.file) {
  1488.                                     xbmc.periodicUpdater.currentlyPlayingFile = currentItem.file;
  1489.                                     $.extend(currentItem, {
  1490.                                         xbmcMediaType: activePlayer
  1491.                                     });
  1492.                                     xbmc.periodicUpdater.fireCurrentlyPlayingChanged(currentItem);
  1493.                                 }
  1494.  
  1495.                                 // current time
  1496.                                 if (xbmc.periodicUpdater.progress != time) {
  1497.                                     xbmc.periodicUpdater.fireProgressChanged({"time": time, total: currentItem.duration});
  1498.                                     xbmc.periodicUpdater.progress = time;
  1499.                                 }
  1500.                             },
  1501.  
  1502.                             null, null, false // not async
  1503.                         );
  1504.                     }
  1505.  
  1506.                 }
  1507.  
  1508.                 setTimeout($.proxy(this, "periodicStep"), 5000);
  1509.             }
  1510.         } // END xbmc.periodicUpdater
  1511.     }); // END xbmc
  1512.  
  1513. })(jQuery);
  1514.  
  1515.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement