Advertisement
frolick

lib.xbmc.js

Oct 13th, 2011
299
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: 'GoPrevious', next: 'GoNext', 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.  
  335.                         if (response.result[0].type != '') {
  336.                             xbmc.sendCommand(
  337.                                 '{"jsonrpc": "2.0", "method": "Player.' + commands[settings.type] + '", "params": { "playerid": ' + response.result[0].playerid + ' }, "id": 1}',
  338.                                 settings.onSuccess,
  339.                                 settings.onError
  340.                             );
  341.                         }
  342.                     },
  343.                     settings.onError
  344.                 );
  345.                 return true;
  346.             }
  347.             return false;
  348.         },
  349.  
  350.  
  351.  
  352.         seekPercentage: function(options) {
  353.             var settings = {
  354.                 percentage: 0,
  355.                 onSuccess: null,
  356.                 onError: null
  357.             };
  358.             $.extend(settings, options);
  359.  
  360.             xbmc.sendCommand(
  361.                 '{"jsonrpc": "2.0", "method": "Player.GetActivePlayers", "id": 1}',
  362.  
  363.                 function (response) {
  364.                     var playerResult = response.result;
  365.                     var player = '';
  366.  
  367.                     if (playerResult.audio) {
  368.                         player = 'Audio';
  369.  
  370.                     } else if (playerResult.video) {
  371.                         player = 'Video';
  372.  
  373.                     } else {
  374.                         // No player is active
  375.                         return;
  376.                     }
  377.  
  378.                     xbmc.sendCommand(
  379.                         '{"jsonrpc": "2.0", "method": "' + player + 'Player.SeekPercentage", "params": ' + settings.percentage + ', "id": 1}',
  380.  
  381.                         settings.onSuccess,
  382.                         settings.onError
  383.                     );
  384.                 },
  385.  
  386.                 settings.onError
  387.             );
  388.         },
  389.  
  390.  
  391.  
  392.         getArtists: function(options) {
  393.             var settings = {
  394.                 onSuccess: null,
  395.                 onError: null
  396.             };
  397.             $.extend(settings, options);
  398.  
  399.             xbmc.sendCommand(
  400.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetArtists", "params": {"sort": { "order": "ascending", "method": "artist" } }, "id": 1}',
  401.  
  402.                 function(response) {
  403.                     settings.onSuccess(response.result);
  404.                 },
  405.  
  406.                 settings.onError
  407.             );
  408.         },
  409.  
  410.  
  411.  
  412.         getArtistsAlbums: function(options) {
  413.             var settings = {
  414.                 artistid: 0,
  415.                 onSuccess: null,
  416.                 onError: null
  417.             };
  418.             $.extend(settings, options);
  419.  
  420.             xbmc.sendCommand(
  421.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": { "artistid" : ' + settings.artistid + ', "properties": ["artist", "genre", "rating", "thumbnail"] }, "id": 1}',
  422.  
  423.                 function(response) {
  424.                     settings.onSuccess(response.result);
  425.                 },
  426.  
  427.                 settings.onError
  428.             );
  429.         },
  430.  
  431.  
  432.  
  433.         getAlbums: function(options) {
  434.             var settings = {
  435.                 onSuccess: null,
  436.                 onError: null
  437.             };
  438.             $.extend(settings, options);
  439.  
  440.             var order = mkf.cookieSettings.get('albumOrder')=='album'? 'label' : 'artist';
  441.  
  442.             xbmc.sendCommand(
  443.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetAlbums", "params": {"properties": ["artist", "genre", "rating", "thumbnail"], "sort": { "order": "ascending", "method": "' + order + '" } }, "id": 1}',
  444.  
  445.                 function(response) {
  446.                     settings.onSuccess(response.result);
  447.                 },
  448.  
  449.                 settings.onError
  450.             );
  451.         },
  452.  
  453.  
  454.  
  455.         addSongToPlaylist: function(options) {
  456.             var settings = {
  457.                 songid: 0,
  458.                 onSuccess: null,
  459.                 onError: null,
  460.                 async: true
  461.             };
  462.             $.extend(settings, options);
  463.  
  464.             xbmc.sendCommand(
  465.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": {"item": {"songid": ' + settings.songid + '}, "playlistid": 0}, "id": 1}',
  466.                 settings.onSuccess,
  467.                 settings.onError,
  468.                 null,
  469.                 settings.async
  470.             );
  471.         },
  472.  
  473.  
  474.  
  475.         addAudioFileToPlaylist: function(options) {
  476.             var settings = {
  477.                 file: '',
  478.                 onSuccess: null,
  479.                 onError: null,
  480.                 async: true
  481.             };
  482.             $.extend(settings, options);
  483.  
  484.             xbmc.sendCommand(
  485.                 //'{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "item": {"file": "' + settings.file.replace(/\\/g, "\\\\") + '"} }, "id": 1}',
  486.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "item": {"file": "' + settings.file.replace(/\\/g, "\\\\") + '"}, "playlistid": 0 }, "id": 1}',
  487.                 settings.onSuccess,
  488.                 settings.onError,
  489.                 null,
  490.                 settings.async
  491.             );
  492.         },
  493.  
  494.  
  495.  
  496.         addAudioFolderToPlaylist: function(options) {
  497.             var settings = {
  498.                 folder: '',
  499.                 onSuccess: null,
  500.                 onError: null
  501.             };
  502.             $.extend(settings, options);
  503.  
  504.             xbmc.getDirectory({
  505.                 media: 'Audio',
  506.                 directory: settings.folder.replace(/\\/g, "\\\\"),
  507.  
  508.                 onSuccess: function(result) {
  509.                     var error = false;
  510.                     var files = result.files;
  511.                     if (files) {
  512.                         files.sort(function(a, b) {
  513.                             if (a.file < b.file) return -1;
  514.                             if (a.file > b.file) return 1;
  515.                             return 0;
  516.                         });
  517.                         $.each(files, function(i, file)  {
  518.                             xbmc.addAudioFileToPlaylist({
  519.                                 'file': file.file,
  520.                                 onError: function() {
  521.                                     error = true;
  522.                                 },
  523.                                 async: false
  524.                             });
  525.                         });
  526.                     }
  527.                     if (error) {
  528.                         settings.onError(mkf.lang.get('message_failed_add_files_to_playlist'));
  529.                     } else {
  530.                         settings.onSuccess();
  531.                     }
  532.                 },
  533.  
  534.                 onError: function() {
  535.                     settings.onError(mkf.lang.get('message_failed_folders_content'));
  536.                 }
  537.             });
  538.         },
  539.  
  540.  
  541. /*
  542.         addAlbumToPlaylist: function(options) {
  543.             var settings = {
  544.                 albumid: 0,
  545.                 onSuccess: null,
  546.                 onError: null
  547.             };
  548.             $.extend(settings, options);
  549.  
  550.             // Comparator to sort albums by tracknumber ASC
  551.             var songComparator = function(a, b) {
  552.                 return a.tracknumber - b.tracknumber;
  553.             }
  554.  
  555.             xbmc.sendCommand(
  556.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": {"albumid": ' + settings.albumid + ', "properties": ["track"]}, "id": 1}',
  557.  
  558.                 function(response) {
  559.                     if (!response.result || !response.result.songs) {
  560.                         settings.onError(mkf.lang.get('message_album_not_found'));
  561.                         return;
  562.                     }
  563.  
  564.                     var songs = response.result.songs;
  565.                     songs.sort(songComparator); // sort by tracknumber ASC
  566.                     var errors = 0;
  567.  
  568.                     // add each song of the album to the playlist
  569.                     $.each(songs, function(i, song)  {
  570.                         // add Song to playlist ... max. 2 retries if add failed
  571.                         xbmc.addSongToPlaylist({songid: song.songid, async: false, onError: function() {
  572.                             xbmc.addSongToPlaylist({songid: song.songid, async: false, onError: function() {
  573.                                 xbmc.addSongToPlaylist({songid: song.songid, async: false, onError: function() {
  574.                                     errors += 1;
  575.                                 }});
  576.                             }});
  577.                         }});
  578.                     });
  579.  
  580.                     if (errors != 0) {
  581.                         settings.onError(mkf.lang.get('message_failed_add_songs_to_playlist', [errors]));
  582.                     } else {
  583.                         settings.onSuccess();
  584.                     }
  585.                 },
  586.  
  587.                 function(response) {
  588.                     settings.onError(mkf.lang.get('message_failed_albums_songs'));
  589.                 }
  590.             );
  591.         },
  592. */
  593.         addAlbumToPlaylist: function(options) {
  594.             var settings = {
  595.                 albumid: 0,
  596.                 onSuccess: null,
  597.                 onError: null
  598.             };
  599.             $.extend(settings, options);
  600.  
  601.             xbmc.sendCommand(
  602.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": {"item": {"albumid": ' + settings.albumid + '}, "playlistid": 0}, "id": 1}',
  603.                
  604.                 function(response) {
  605.                     settings.onSuccess()
  606.                 },
  607.                
  608.                 function(response) {
  609.                     settings.onError(mkf.lang.get('message_failed_albums_songs'));
  610.                 }
  611.             );         
  612.         },
  613.  
  614.  
  615.         clearAudioPlaylist: function(options) {
  616.             var settings = {
  617.                 onSuccess: null,
  618.                 onError: null,
  619.             };
  620.             $.extend(settings, options);
  621.  
  622.             xbmc.sendCommand(
  623.                 '{"jsonrpc": "2.0", "method": "Playlist.Clear", "params": { "playlistid": 0 }, "id": 1}',
  624.                 settings.onSuccess,
  625.                 settings.onError
  626.             );
  627.         },
  628.  
  629.  
  630.  
  631.         playAudio: function(options) {
  632.             var settings = {
  633.                 item: 0,
  634.                 onSuccess: null,
  635.                 onError: null,
  636.             };
  637.             $.extend(settings, options);
  638.  
  639.             xbmc.sendCommand(
  640.                 // '{"jsonrpc": "2.0", "method": "Player.Open", "params": {"item": ' + settings.item + '}, "id": 1}',
  641.                 '{"jsonrpc": "2.0", "method": "Player.Open", "params" : { "item" : { "playlistid" : 0, "position": ' + settings.item + ' } }, "id": 1}',
  642.                 settings.onSuccess,
  643.                 function(response) {
  644.                     settings.onError(mkf.lang.get('message_failed_play' + 'settings.item'));
  645.                 }
  646.             );
  647.         },
  648.  
  649.  
  650.  
  651.         playAlbum: function(options) {
  652.             var settings = {
  653.                 albumid: 0,
  654.                 onSuccess: null,
  655.                 onError: null,
  656.             };
  657.             $.extend(settings, options);
  658.  
  659.             this.clearAudioPlaylist({
  660.                 onSuccess: function() {
  661.                     xbmc.addAlbumToPlaylist({
  662.                         albumid: settings.albumid,
  663.  
  664.                         onSuccess: function() {
  665.                             xbmc.playAudio({
  666.                                 onSuccess: settings.onSuccess,
  667.                                 onError: function(errorText) {
  668.                                     settings.onError(errorText);
  669.                                 }
  670.                             });
  671.                         },
  672.  
  673.                         onError: function(errorText) {
  674.                             settings.onError(errorText);
  675.                         }
  676.                     });
  677.                 },
  678.  
  679.                 onError: function() {
  680.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  681.                 }
  682.             });
  683.         },
  684.  
  685.  
  686.  
  687.         playSong: function(options) {
  688.             var settings = {
  689.                 songid: 0,
  690.                 onSuccess: null,
  691.                 onError: null,
  692.             };
  693.             $.extend(settings, options);
  694.  
  695.             this.clearAudioPlaylist({
  696.                 onSuccess: function() {
  697.                     xbmc.addSongToPlaylist({
  698.                         songid: settings.songid,
  699.  
  700.                         onSuccess: function() {
  701.                             xbmc.playAudio({
  702.                                 onSuccess: settings.onSuccess,
  703.                                 onError: function(errorText) {
  704.                                     settings.onError(errorText);
  705.                                 }
  706.                             });
  707.                         },
  708.  
  709.                         onError: function() {
  710.                             settings.onError(mkf.lang.get('message_failed_add_song_to_playlist'));
  711.                         }
  712.                     });
  713.                 },
  714.  
  715.                 onError: function() {
  716.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  717.                 }
  718.             });
  719.         },
  720.  
  721.  
  722.  
  723.         playAudioFile: function(options) {
  724.             var settings = {
  725.                 file: '',
  726.                 onSuccess: null,
  727.                 onError: null,
  728.             };
  729.             $.extend(settings, options);
  730.  
  731.             this.clearAudioPlaylist({
  732.                 onSuccess: function() {
  733.                     xbmc.addAudioFileToPlaylist({
  734.                         file: settings.file,
  735.  
  736.                         onSuccess: function() {
  737.                             xbmc.playAudio({
  738.                                 onSuccess: settings.onSuccess,
  739.                                 onError: function(errorText) {
  740.                                     settings.onError(errorText);
  741.                                 }
  742.                             });
  743.                         },
  744.  
  745.                         onError: function() {
  746.                             settings.onError(mkf.lang.get('message_failed_add_file_to_playlist'));
  747.                         }
  748.                     });
  749.                 },
  750.  
  751.                 onError: function() {
  752.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  753.                 }
  754.             });
  755.         },
  756.  
  757.  
  758.  
  759.         playAudioFolder: function(options) {
  760.             var settings = {
  761.                 folder: '',
  762.                 onSuccess: null,
  763.                 onError: null,
  764.             };
  765.             $.extend(settings, options);
  766.  
  767.             this.clearAudioPlaylist({
  768.                 onSuccess: function() {
  769.                     xbmc.addAudioFolderToPlaylist({
  770.                         folder: settings.folder,
  771.  
  772.                         onSuccess: function() {
  773.                             xbmc.playAudio({
  774.                                 onSuccess: settings.onSuccess,
  775.                                 onError: function(errorText) {
  776.                                     settings.onError(errorText);
  777.                                 }
  778.                             });
  779.                         },
  780.  
  781.                         onError: function(errorText) {
  782.                             settings.onError(errorText);
  783.                         }
  784.                     });
  785.                 },
  786.  
  787.                 onError: function() {
  788.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  789.                 }
  790.             });
  791.         },
  792.  
  793.  
  794.  
  795.         getAlbumsSongs: function(options) {
  796.             var settings = {
  797.                 albumid: 0,
  798.                 onSuccess: null,
  799.                 onError: null,
  800.             };
  801.             $.extend(settings, options);
  802.  
  803.             xbmc.sendCommand(
  804.                 '{"jsonrpc": "2.0", "method": "AudioLibrary.GetSongs", "params": { "albumid": ' + settings.albumid + ', "properties": ["artist", "track"] }, "id": 1}',
  805.  
  806.                 function(response) {
  807.                     settings.onSuccess(response.result);
  808.                 },
  809.  
  810.                 settings.onError
  811.             );
  812.         },
  813.  
  814.  
  815.  
  816.         getAudioPlaylist: function(options) {
  817.             var settings = {
  818.                 onSuccess: null,
  819.                 onError: null,
  820.             };
  821.             $.extend(settings, options);
  822.  
  823.             xbmc.sendCommand(
  824.                 '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "properties": ["title", "album", "artist", "duration"], "playlistid": 0 }, "id": 1}',
  825.  
  826.                 function(response) {
  827.                     settings.onSuccess(response.result);
  828.                 },
  829.  
  830.                 settings.onError
  831.             );
  832.         },
  833.  
  834.  
  835.  
  836.         clearVideoPlaylist: function(options) {
  837.             var settings = {
  838.                 onSuccess: null,
  839.                 onError: null,
  840.             };
  841.             $.extend(settings, options);
  842.  
  843.             xbmc.sendCommand(
  844.                 '{"jsonrpc": "2.0", "method": "Playlist.Clear", "params": { "playlistid": 1 }, "id": 1}',
  845.                 settings.onSuccess,
  846.                 settings.onError
  847.             );
  848.         },
  849.  
  850.  
  851.  
  852.         playVideo: function(options) {
  853.             var settings = {
  854.                 item: 0,
  855.                 onSuccess: null,
  856.                 onError: null,
  857.             };
  858.             $.extend(settings, options);
  859.  
  860.             xbmc.sendCommand(
  861.                 // '{"jsonrpc": "2.0", "method": "Player.Open", "params": {"item": ' + settings.item + '}, "id": 1}',
  862.                 '{"jsonrpc": "2.0", "method": "Player.Open", "params" : { "item" : { "playlistid" : 1, "position": ' + settings.item + ' } }, "id": 1}',
  863.                 settings.onSuccess,
  864.                 function(response) {
  865.                     settings.onError(mkf.lang.get('message_failed_play'));
  866.                 }
  867.             );
  868.         },
  869.  
  870.  
  871.  
  872.         addVideoFileToPlaylist: function(options) {
  873.             var settings = {
  874.                 file: '',
  875.                 onSuccess: null,
  876.                 onError: null,
  877.                 async: true
  878.             };
  879.             $.extend(settings, options);
  880.  
  881.             xbmc.sendCommand(
  882.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": { "file": "' + settings.file.replace(/\\/g, "\\\\") + '", "playlistid": 1 }, "id": 1}',
  883.                 settings.onSuccess,
  884.                 settings.onError,
  885.                 null,
  886.                 settings.async
  887.             );
  888.         },
  889.  
  890.  
  891.  
  892.         addVideoFolderToPlaylist: function(options) {
  893.             var settings = {
  894.                 folder: '',
  895.                 onSuccess: null,
  896.                 onError: null
  897.             };
  898.             $.extend(settings, options);
  899.  
  900.  
  901.             xbmc.getDirectory({
  902.                 media: 'Video',
  903.                 directory: settings.folder.replace(/\\/g, "\\\\"),
  904.  
  905.                 onSuccess: function(result) {
  906.                     var error = false;
  907.                     var files = result.files;
  908.                     if (files) {
  909.                         files.sort(function(a, b) {
  910.                             if (a.file < b.file) return -1;
  911.                             if (a.file > b.file) return 1;
  912.                             return 0;
  913.                         });
  914.                         alert(objToStr(files,''));
  915.                         $.each(files, function(i, file)  {
  916.                             xbmc.addVideoFileToPlaylist({
  917.                                 'file': file.file,
  918.                                 onError: function() {
  919.                                     error = true;
  920.                                 },
  921.                                 async: false
  922.                             });
  923.                         });
  924.                     }
  925.                     if (error) {
  926.                         settings.onError(mkf.lang.get('message_failed_add_files_to_playlist'));
  927.                     } else {
  928.                         settings.onSuccess();
  929.                     }
  930.                 },
  931.  
  932.                 onError: function() {
  933.                     settings.onError(mkf.lang.get('message_failed_folders_content'));
  934.                 }
  935.             });
  936.         },
  937.  
  938.  
  939.  
  940.         addMovieToPlaylist: function(options) {
  941.             var settings = {
  942.                 movieid: 0,
  943.                 onSuccess: null,
  944.                 onError: null,
  945.             };
  946.             $.extend(settings, options);
  947.         /*
  948.             function myobject(){
  949.             this.movieid = 0;
  950.             }
  951.             var args = new myobject();
  952.             args.movieid = settings.movieid;
  953.         */
  954.             xbmc.sendCommand(
  955.                 //'{"jsonrpc": "2.0", "method": "VideoPlaylist.Add", "params": {"movieid": ' + settings.movieid + '}, "id": 1}',
  956.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": {"item": {"movieid": ' + settings.movieid + '}, "playlistid": 1}, "id": 1}',
  957.                 settings.onSuccess,
  958.                 settings.onError,
  959.                 null,
  960.                 settings.async
  961.             );
  962.         },
  963.  
  964.  
  965.  
  966.         playMovie: function(options) {
  967.             var settings = {
  968.                 movieid: 0,
  969.                 onSuccess: null,
  970.                 onError: null,
  971.             };
  972.             $.extend(settings, options);
  973.  
  974.             this.clearVideoPlaylist({
  975.                 onSuccess: function() {
  976.                     xbmc.addMovieToPlaylist({
  977.                         movieid: settings.movieid,
  978.  
  979.                         onSuccess: function() {
  980.                             xbmc.playVideo({
  981.                                 onSuccess: settings.onSuccess,
  982.                                 onError: function(errorText) {
  983.                                     settings.onError(errorText);
  984.                                 }
  985.                             });
  986.                         },
  987.  
  988.                         onError: function() {
  989.                             settings.onError(mkf.lang.get('message_failed_add_movie_to_playlist'));
  990.                         }
  991.                     });
  992.                 },
  993.  
  994.                 onError: function() {
  995.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  996.                 }
  997.             });
  998.         },
  999.  
  1000.  
  1001.  
  1002.         playVideoFile: function(options) {
  1003.             var settings = {
  1004.                 file: '',
  1005.                 onSuccess: null,
  1006.                 onError: null,
  1007.             };
  1008.             $.extend(settings, options);
  1009.  
  1010.             this.clearVideoPlaylist({
  1011.                 onSuccess: function() {
  1012.                     xbmc.addVideoFileToPlaylist({
  1013.                         file: settings.file,
  1014.  
  1015.                         onSuccess: function() {
  1016.                             xbmc.playVideo({
  1017.                                 onSuccess: settings.onSuccess,
  1018.                                 onError: function(errorText) {
  1019.                                     settings.onError(errorText);
  1020.                                 }
  1021.                             });
  1022.                         },
  1023.  
  1024.                         onError: function() {
  1025.                             settings.onError(mkf.lang.get('message_failed_add_file_to_playlist'));
  1026.                         }
  1027.                     });
  1028.                 },
  1029.  
  1030.                 onError: function() {
  1031.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  1032.                 }
  1033.             });
  1034.         },
  1035.  
  1036.  
  1037.  
  1038.         playVideoFolder: function(options) {
  1039.             var settings = {
  1040.                 folder: '',
  1041.                 onSuccess: null,
  1042.                 onError: null,
  1043.             };
  1044.             $.extend(settings, options);
  1045.  
  1046.             this.clearVideoPlaylist({
  1047.                 onSuccess: function() {
  1048.                     xbmc.addVideoFolderToPlaylist({
  1049.                         folder: settings.folder,
  1050.  
  1051.                         onSuccess: function() {
  1052.                             xbmc.playVideo({
  1053.                                 onSuccess: settings.onSuccess,
  1054.                                 onError: function(errorText) {
  1055.                                     settings.onError(errorText);
  1056.                                 }
  1057.                             });
  1058.                         },
  1059.  
  1060.                         onError: function(errorText) {
  1061.                             settings.onError(errorText);
  1062.                         }
  1063.                     });
  1064.                 },
  1065.  
  1066.                 onError: function() {
  1067.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  1068.                 }
  1069.             });
  1070.         },
  1071.  
  1072.  
  1073.  
  1074.         /*getMovieInfo: function(options) {
  1075.             var settings = {
  1076.                 movieid: 0,
  1077.                 onSuccess: null,
  1078.                 onError: null,
  1079.             };
  1080.             $.extend(settings, options);
  1081.  
  1082.             // TODO better: do not get all movies
  1083.             xbmc.sendCommand(
  1084.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": { "properties" : ["genre", "director", "plot", "title", "originaltitle", "runtime", "year", "rating"] }, "id": 1}',
  1085.  
  1086.                 function (response) {
  1087.                     var movies = response.result.movies;
  1088.                     var result = null;
  1089.  
  1090.                     if (response.result.total > 0) {
  1091.                         $.each(movies, function(i, movie)  {
  1092.                             if (movie.movieid == settings.movieid) {
  1093.                                 result = movie;
  1094.                                 return false;
  1095.                             }
  1096.                         });
  1097.                     }
  1098.  
  1099.                     settings.onSuccess(result);
  1100.                 },
  1101.  
  1102.                 settings.onError
  1103.             );
  1104.         },*/
  1105.  
  1106.  
  1107.  
  1108.         getMovies: function(options) {
  1109.             var settings = {
  1110.                 onSuccess: null,
  1111.                 onError: null,
  1112.             };
  1113.             $.extend(settings, options);
  1114.  
  1115.             xbmc.sendCommand(
  1116.                 //'{"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}',
  1117.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetMovies", "params": {"properties" : ["genre", "director", "plot", "title", "originaltitle", "runtime", "year", "rating", "thumbnail"], "sort": { "order": "ascending", "method": "label" } }, "id": 1}',
  1118.                 function(response) {
  1119.                     settings.onSuccess(response.result);
  1120.                 },
  1121.                 settings.onError
  1122.             );
  1123.         },
  1124.  
  1125.  
  1126.  
  1127.         addEpisodeToPlaylist: function(options) {
  1128.             var settings = {
  1129.                 episodeid: 0,
  1130.                 onSuccess: null,
  1131.                 onError: null,
  1132.             };
  1133.             $.extend(settings, options);
  1134.  
  1135.             xbmc.sendCommand(
  1136.                 //'{"jsonrpc": "2.0", "method": "VideoPlaylist.Add", "params": {"episodeid": ' + settings.episodeid + '}, "id": 1}',
  1137.                 '{"jsonrpc": "2.0", "method": "Playlist.Add", "params": {"item": {"episodeid": ' + settings.episodeid + '}, "playlistid": 1}, "id": 1}',
  1138.                 settings.onSuccess,
  1139.                 settings.onError,
  1140.                 null,
  1141.                 settings.async
  1142.             );
  1143.         },
  1144.  
  1145.  
  1146.  
  1147.         playEpisode: function(options) {
  1148.             var settings = {
  1149.                 episodeid: 0,
  1150.                 onSuccess: null,
  1151.                 onError: null,
  1152.             };
  1153.             $.extend(settings, options);
  1154.  
  1155.             this.clearVideoPlaylist({
  1156.                 onSuccess: function() {
  1157.                     xbmc.addEpisodeToPlaylist({
  1158.                         episodeid: settings.episodeid,
  1159.  
  1160.                         onSuccess: function() {
  1161.                             xbmc.playVideo({
  1162.                                 onSuccess: settings.onSuccess,
  1163.                                 onError: function(errorText) {
  1164.                                     settings.onError(errorText);
  1165.                                 }
  1166.                             });
  1167.                         },
  1168.  
  1169.                         onError: function() {
  1170.                             settings.onError(mkf.lang.get('message_failed_add_episode_to_playlist'));
  1171.                         }
  1172.                     });
  1173.                 },
  1174.  
  1175.                 onError: function() {
  1176.                     settings.onError(mkf.lang.get('message_failed_clear_playlist'));
  1177.                 }
  1178.             });
  1179.         },
  1180.  
  1181.  
  1182.  
  1183.         getTvShows: function(options) {
  1184.             var settings = {
  1185.                 onSuccess: null,
  1186.                 onError: null,
  1187.             };
  1188.             $.extend(settings, options);
  1189.  
  1190.             xbmc.sendCommand(
  1191.                 //'{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "start": 0, "properties": ["genre", "director", "plot", "title", "originaltitle", "runtime", "year", "rating"] }, "id": 1}',
  1192.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetTVShows", "params": { "properties": ["genre", "plot", "title", "originaltitle", "year", "rating", "thumbnail"] }, "id": 1}',
  1193.                 function(response) {
  1194.                     settings.onSuccess(response.result);
  1195.                 },
  1196.                 settings.onError
  1197.             );
  1198.         },
  1199.  
  1200.  
  1201.  
  1202.         getSeasons: function(options) {
  1203.             var settings = {
  1204.                 tvshowid: 0,
  1205.                 onSuccess: null,
  1206.                 onError: null,
  1207.             };
  1208.             $.extend(settings, options);
  1209.  
  1210.             xbmc.sendCommand(
  1211.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetSeasons", "params": { "tvshowid": ' + settings.tvshowid + ', "properties": ["season"]}, "id": 1}',
  1212.                 function(response) {
  1213.                     settings.onSuccess(response.result);
  1214.                 },
  1215.                 settings.onError
  1216.             );
  1217.         },
  1218.  
  1219.  
  1220.  
  1221.         getEpisodes: function(options) {
  1222.             var settings = {
  1223.                 tvshowid: 0,
  1224.                 season: 0,
  1225.                 onSuccess: null,
  1226.                 onError: null,
  1227.             };
  1228.             $.extend(settings, options);
  1229.  
  1230.             xbmc.sendCommand(
  1231.                 '{"jsonrpc": "2.0", "method": "VideoLibrary.GetEpisodes", "params": { "tvshowid": ' + settings.tvshowid + ', "season" : ' + settings.season + ', "properties": ["episode"], "sort": { "order": "ascending", "method": "episode" } }, "id": 1}',
  1232.                 function(response) {
  1233.                     settings.onSuccess(response.result);
  1234.                 },
  1235.                 settings.onError
  1236.             );
  1237.         },
  1238.  
  1239.  
  1240.  
  1241.         getVideoPlaylist: function(options) {
  1242.             var settings = {
  1243.                 onSuccess: null,
  1244.                 onError: null,
  1245.             };
  1246.             $.extend(settings, options);
  1247.  
  1248.             xbmc.sendCommand(
  1249.                 '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "playlistid": 1}, "id": 1}',
  1250.  
  1251.                 function(response) {
  1252.                     settings.onSuccess(response.result);
  1253.                 },
  1254.  
  1255.                 settings.onError
  1256.             );
  1257.         },
  1258.  
  1259.  
  1260.  
  1261.         getSources: function(options) {
  1262.             var settings = {
  1263.                 media: 'Audio',
  1264.                 onSuccess: null,
  1265.                 onError: null,
  1266.                 async: true
  1267.             };
  1268.             $.extend(settings, options);
  1269.  
  1270.             xbmc.sendCommand(
  1271.                 '{"jsonrpc": "2.0", "method": "Files.GetSources", "params" : { "media" : "' + (settings.media=='Audio'? 'music' : 'video') + '" }, "id": 1}',
  1272.  
  1273.                 function(response) {
  1274.                     settings.onSuccess(response.result);
  1275.                 },
  1276.  
  1277.                 settings.onError,
  1278.                 null,
  1279.                 settings.async
  1280.             );
  1281.         },
  1282.  
  1283.  
  1284.  
  1285.         getDirectory: function(options) {
  1286.             var settings = {
  1287.                 media: 'Audio',
  1288.                 directory: '',
  1289.                 onSuccess: null,
  1290.                 onError: null,
  1291.                 async: true
  1292.             };
  1293.             $.extend(settings, options);
  1294.  
  1295.             xbmc.sendCommand(
  1296.                 '{"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}',
  1297.  
  1298.                 function(response) {
  1299.                     settings.onSuccess(response.result);
  1300.                 },
  1301.  
  1302.                 settings.onError,
  1303.                 null,
  1304.                 settings.async
  1305.             );
  1306.         }
  1307.  
  1308.  
  1309.  
  1310.     }); // END xbmc
  1311.  
  1312.  
  1313.  
  1314.     $.extend(xbmc, {
  1315.         periodicUpdater: {
  1316.             volumeChangedListener: [],
  1317.             currentlyPlayingChangedListener: [],
  1318.             playerStatusChangedListener: [],
  1319.             progressChangedListener: [],
  1320.  
  1321.             lastVolume: -1,
  1322.             currentlyPlayingFile: null,
  1323.             progress: '',
  1324.             playerStatus: 'stopped',
  1325.             shuffleStatus: false,
  1326.  
  1327.             addVolumeChangedListener: function(fn) {
  1328.                 this.volumeChangedListener.push(fn);
  1329.             },
  1330.  
  1331.             addCurrentlyPlayingChangedListener: function(fn) {
  1332.                 this.currentlyPlayingChangedListener.push(fn);
  1333.             },
  1334.  
  1335.             addPlayerStatusChangedListener: function(fn) {
  1336.                 this.playerStatusChangedListener.push(fn);
  1337.             },
  1338.  
  1339.             addProgressChangedListener: function(fn) {
  1340.                 this.progressChangedListener.push(fn);
  1341.             },
  1342.  
  1343.             firePlayerStatusChanged: function(status) {
  1344.                 $.each(xbmc.periodicUpdater.playerStatusChangedListener, function(i, listener)  {
  1345.                     listener(status);
  1346.                 });
  1347.             },
  1348.  
  1349.             fireCurrentlyPlayingChanged: function(file) {
  1350.                 $.each(xbmc.periodicUpdater.currentlyPlayingChangedListener, function(i, listener)  {
  1351.                     listener(file);
  1352.                 });
  1353.             },
  1354.  
  1355.             fireProgressChanged: function(progress) {
  1356.                 $.each(xbmc.periodicUpdater.progressChangedListener, function(i, listener)  {
  1357.                     listener(progress);
  1358.                 });
  1359.             },
  1360.  
  1361.             start: function() {
  1362.                 setTimeout($.proxy(this, "periodicStep"), 10);
  1363.             },
  1364.  
  1365.             periodicStep: function() {
  1366.  
  1367.                 var curPlayData = {};
  1368.                 var shuffle = false;
  1369.                 var time = '';
  1370.                 var file = '';
  1371.                 var volume = 0;
  1372.  
  1373.                 // ---------------------------------
  1374.                 // ---      Volume Changes       ---
  1375.                 // ---------------------------------
  1376.                 // --- Currently Playing Changes ---
  1377.                 // ---------------------------------
  1378.                 if ((this.volumeChangedListener &&
  1379.                     this.volumeChangedListener.length) ||
  1380.                     (this.currentlyPlayingChangedListener &&
  1381.                     this.currentlyPlayingChangedListener.length) ||
  1382.                     (this.playerStatusChangedListener &&
  1383.                     this.playerStatusChangedListener.length) ||
  1384.                     (this.progressChangedListener &&
  1385.                     this.progressChangedListener.length)) {
  1386.  
  1387.                     var activePlayer = '';
  1388.  
  1389.                     xbmc.sendCommand(
  1390.                         '{"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}',
  1391.  
  1392.                         function (response) {
  1393.                             var infoResult = response.result;
  1394.  
  1395.                             shuffle = (infoResult['Playlist.Random']=="Random"? true: false);
  1396.                             time = infoResult['Player.Time'];
  1397.                             file = infoResult['Player.Filenameandpath'];
  1398.  
  1399.                             var tmp = parseFloat(infoResult['Player.Volume']);
  1400.                             volume = (isNaN(tmp)? 0: (tmp+60)/60*100); // -60 dB to 0 dB (--> 0% to 100%)
  1401.  
  1402.                             curPlayData.duration = infoResult['Player.Duration'];
  1403.                             curPlayData.file = infoResult['Player.Filenameandpath'];
  1404.  
  1405.                             if (infoResult['MusicPlayer.Title'] != "") {
  1406.                                 activePlayer = 'audio';
  1407.                                 curPlayData.title = infoResult['MusicPlayer.Title'];
  1408.                                 curPlayData.album = infoResult['MusicPlayer.Album'];
  1409.                                 curPlayData.artist = infoResult['MusicPlayer.Artist'];
  1410.  
  1411.                             } else if (infoResult['VideoPlayer.Title'] != "") {
  1412.                                 activePlayer = 'video';
  1413.                                 curPlayData.title = infoResult['VideoPlayer.Title'];
  1414.                                 curPlayData.showtitle = infoResult['VideoPlayer.TVShowTitle'];
  1415.  
  1416.                             } else {
  1417.                                 activePlayer = 'none';
  1418.                             }
  1419.                         },
  1420.  
  1421.                         function(response) {
  1422.                             activePlayer = 'none'; // ERROR
  1423.                         },
  1424.  
  1425.                         null, false // not async
  1426.                     );
  1427.  
  1428.                     // has volume changed?
  1429.                     if (volume != xbmc.periodicUpdater.lastVolume) {
  1430.                         $.each(xbmc.periodicUpdater.volumeChangedListener, function(i, listener)  {
  1431.                             listener(volume);
  1432.                         });
  1433.                     }
  1434.  
  1435.                     if (activePlayer == 'none' &&
  1436.                         this.playerStatus != 'stopped') {
  1437.  
  1438.                         this.playerStatus = 'stopped';
  1439.                         this.firePlayerStatusChanged('stopped');
  1440.                     }
  1441.  
  1442.                     // shuffle status changed?
  1443.                     if (this.shuffleStatus != shuffle) {
  1444.                         this.shuffleStatus = shuffle;
  1445.                         this.firePlayerStatusChanged(shuffle? 'shuffleOn': 'shuffleOff');
  1446.                     }
  1447.  
  1448.                     // is playing
  1449.                     if (activePlayer != 'none') {
  1450.                         var request = '';
  1451.  
  1452.                         if (activePlayer == 'audio') {
  1453.                             request = '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "properties": ["title", "album", "artist", "duration"], "playlistid": 0 }, "id": 1}';
  1454.  
  1455.                         } else if (activePlayer == 'video') {
  1456.                             request = '{"jsonrpc": "2.0", "method": "Playlist.GetItems", "params": { "properties": ["title", "season", "episode", "duration", "showtitle"], "playlistid": 1 }, "id": 1}';
  1457.                         }
  1458.  
  1459.                         xbmc.sendCommand(
  1460.                             request,
  1461.  
  1462.                             function (response) {
  1463.                                 var currentPlayer = response.result;
  1464.                                 var currentItem;
  1465.  
  1466.                                 // playlist may be cleared. Use data retrieved by GetInfoLabels
  1467.                                 if (!currentPlayer.items || !currentPlayer.items[currentPlayer.current]) {
  1468.                                     currentItem = curPlayData;
  1469.  
  1470.                                 } else {
  1471.                                     currentItem = currentPlayer.items[currentPlayer.current];
  1472.                                     $.extend(currentItem, curPlayData);
  1473.                                 }
  1474.  
  1475.  
  1476.                                 if (!currentPlayer.playing) {
  1477.                                     // not playing
  1478.                                     if (xbmc.periodicUpdater.playerStatus != 'stopped') {
  1479.                                         xbmc.periodicUpdater.playerStatus = 'stopped';
  1480.                                         xbmc.periodicUpdater.firePlayerStatusChanged('stopped');
  1481.                                     }
  1482.  
  1483.                                 } else if (currentPlayer.paused && xbmc.periodicUpdater.playerStatus != 'paused') {
  1484.                                     xbmc.periodicUpdater.playerStatus = 'paused';
  1485.                                     xbmc.periodicUpdater.firePlayerStatusChanged('paused');
  1486.  
  1487.                                 } else if (!currentPlayer.paused && xbmc.periodicUpdater.playerStatus != 'playing') {
  1488.                                     xbmc.periodicUpdater.playerStatus = 'playing';
  1489.                                     xbmc.periodicUpdater.firePlayerStatusChanged('playing');
  1490.                                 }
  1491.  
  1492.                                 // has current file changed?
  1493.                                 if (xbmc.periodicUpdater.currentlyPlayingFile != currentItem.file) {
  1494.                                     xbmc.periodicUpdater.currentlyPlayingFile = currentItem.file;
  1495.                                     $.extend(currentItem, {
  1496.                                         xbmcMediaType: activePlayer
  1497.                                     });
  1498.                                     xbmc.periodicUpdater.fireCurrentlyPlayingChanged(currentItem);
  1499.                                 }
  1500.  
  1501.                                 // current time
  1502.                                 if (xbmc.periodicUpdater.progress != time) {
  1503.                                     xbmc.periodicUpdater.fireProgressChanged({"time": time, total: currentItem.duration});
  1504.                                     xbmc.periodicUpdater.progress = time;
  1505.                                 }
  1506.                             },
  1507.  
  1508.                             null, null, false // not async
  1509.                         );
  1510.                     }
  1511.  
  1512.                 }
  1513.  
  1514.                 setTimeout($.proxy(this, "periodicStep"), 5000);
  1515.             }
  1516.         } // END xbmc.periodicUpdater
  1517.     }); // END xbmc
  1518.  
  1519. })(jQuery);
  1520.  
  1521.  
  1522.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement