index.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="apple-mobile-web-app-capable" content="yes" />
  5. <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
  6. <meta charset="UTF-8">
  7. <meta name="theme-color" content="#4b75ff">
  8. <link rel="stylesheet" href="../script/semantic/semantic.min.css">
  9. <script src="../script/jquery.min.js"></script>
  10. <script src="../script/semantic/semantic.min.js"></script>
  11. <script src="../script/ao_module.js"></script>
  12. <script src="script/DPlayer.min.js"></script>
  13. <link rel="manifest" crossorigin="use-credentials" href="manifest.json">
  14. <title>Video</title>
  15. <style>
  16. html, body{
  17. background-color:rgba(250,250,250,0.95);
  18. padding:0px !important;
  19. margin: 0px;
  20. }
  21. #dplayer{
  22. display:inline-block;
  23. width:70%;
  24. vertical-align: top;
  25. }
  26. .playerwrapper{
  27. background-color:black;
  28. width:100%;
  29. margin-bottom:12px;
  30. }
  31. @media only screen and (max-width: 1900px) {
  32. #dplayer{
  33. width:50%;
  34. }
  35. }
  36. @media only screen and (max-width: 1500px) {
  37. #dplayer{
  38. width:60%;
  39. }
  40. }
  41. @media only screen and (max-width: 1024px) {
  42. #dplayer{
  43. width:70%;
  44. }
  45. }
  46. @media only screen and (max-width: 600px) {
  47. #dplayer{
  48. width:100%;
  49. }
  50. }
  51. .playing{
  52. background-color:#ededed;
  53. }
  54. .videoObject{
  55. padding:6px !important;
  56. cursor: pointer;
  57. }
  58. .videoObject:hover{
  59. background-color: #ffdd91;
  60. }
  61. .playlistObject{
  62. padding: 0.8em !important;
  63. cursor: pointer;
  64. }
  65. .playlistObject:hover{
  66. background-color: #ffdd91;
  67. }
  68. .playlistObject.active{
  69. background-color:#ededed;
  70. }
  71. </style>
  72. </head>
  73. <body>
  74. <!-- Viewing Panel-->
  75. <div class="playerwrapper" align="center">
  76. <div id="dplayer" class="unstyled" align="left"></div>
  77. </div>
  78. <!-- PlayList-->
  79. <div class="ui container">
  80. <h3 class="ui header">
  81. <span id="videoname">No Video Loaded</span>
  82. <div class="sub header"><span id="playlistName">N/A</span> / <span id="ext">[no_media]</span></div>
  83. </h3>
  84. <div class="ui segment">
  85. <p><i class="expand icon"></i>Screen Size</p>
  86. <!--
  87. <button class="ui tiny button" onclick="setScreenSize('50%');">
  88. Small
  89. </button>
  90. -->
  91. <button class="ui tiny button" onclick="setScreenSize('70%'); previousScreenSize='70%';">
  92. Normal
  93. </button>
  94. <button class="ui tiny button" onclick="setScreenSize('100%');previousScreenSize='100%';">
  95. Full Width
  96. </button>
  97. <div class="ui toggle right floated checkbox">
  98. <input id="autoplayToggle" type="checkbox" name="autoplay" onchange="setAutoplay(this);">
  99. <label>Autoplay</label>
  100. </div>
  101. </div>
  102. <div class="ui fluid segment">
  103. <div class="ui icon tiny right floated basic buttons">
  104. <button onclick="playPreviousVideo();" class="ui tiny basic icon button"><i class="step backward icon"></i></button>
  105. <button onclick="jumpToPlayingPlaylist();" class="ui tiny basic icon button"><i class="list icon"></i></button>
  106. <button onclick="jumpToPlayingVideo();" class="ui tiny basic icon button"><i class="arrow down icon"></i></button>
  107. <button onclick="playNextVideo();" class="ui tiny basic icon button"><i class="step forward icon"></i></button>
  108. </div>
  109. <div id="playList" class="ui accordion">
  110. <div class="title">
  111. <i class="dropdown icon"></i>
  112. <i class="list icon"></i> PlayLists
  113. </div>
  114. <div class="content">
  115. <div id="playListSelector" class="ui relaxed divided list">
  116. </div>
  117. </div>
  118. <div class="title">
  119. <i class="dropdown icon"></i>
  120. <i class="file icon"></i>PlayList Videos
  121. </div>
  122. <div class="content">
  123. <div id="videolist" class="ui relaxed divided list">
  124. </div>
  125. </div>
  126. </div>
  127. </div>
  128. <br><br><br>
  129. </div>
  130. <script>
  131. var playerObject;
  132. var AllPlaylist = [];
  133. var currentPlaylist = [];
  134. var currentPlaying;
  135. //var unsortedVideoFiles = [];
  136. var autoPlay = false;
  137. var previousScreenSize = "70%";
  138. $('.ui.dropdown').dropdown();
  139. init();
  140. initPlaylist();
  141. //Check if there are file dropped into this interface. If yes, redirect to embedded
  142. var infile = ao_module_loadInputFiles();
  143. if (infile != null){
  144. window.location.href = "embedded.html" + window.location.hash;
  145. }
  146. autoPlay = (ao_module_storage.loadStorage("Video","autoplay") == "true");
  147. if (autoPlay){
  148. $("#autoplayToggle").attr("checked",true);
  149. }
  150. function init(){
  151. //Removed set global volume and isolate two systems
  152. /*var defaultVol = localStorage.getItem("global_volume");
  153. if (defaultVol == null || defaultVol == "" || defaultVol == undefined){
  154. defaultVol = 0.4;
  155. }
  156. */
  157. const dp = new DPlayer({
  158. container: document.getElementById('dplayer'),
  159. autoplay: false,
  160. //volume: parseFloat(defaultVol),
  161. video: {
  162. pic: 'img/thumbnail.png',
  163. }
  164. });
  165. playerObject = dp;
  166. /*
  167. dp.on("volumechange",function(){
  168. var newVol = dp.volume();
  169. if (localStorage){
  170. localStorage.setItem("global_volume",newVol);
  171. }
  172. });
  173. */
  174. //handle autoplay on end
  175. dp.on('ended', function() {
  176. if (autoPlay){
  177. //Play next item in list
  178. playNextVideo();
  179. }
  180. });
  181. //Handle full screen
  182. dp.on('fullscreen', function() {
  183. //previousScreenSize = $("#dplayer").css("width");
  184. setScreenSize("100%");
  185. });
  186. dp.on('fullscreen_cancel', function() {
  187. setScreenSize(previousScreenSize);
  188. });
  189. }
  190. function playNextVideo(){
  191. var nextToPlay = 0;
  192. for (var i =0; i < currentPlaylist.length; i++){
  193. if (currentPlaylist[i].Filename == currentPlaying){
  194. nextToPlay = i + 1;
  195. if (nextToPlay >= currentPlaylist.length){
  196. //last video. loop back to first esp
  197. nextToPlay = 0;
  198. }
  199. }
  200. }
  201. //Play the selected item
  202. var nextPlayObject = currentPlaylist[nextToPlay];
  203. if (nextPlayObject == undefined){
  204. //No playlist or no object to play
  205. return;
  206. }
  207. console.log(currentPlaylist[nextToPlay],nextToPlay);
  208. $("#videoname").text(nextPlayObject.Filename);
  209. $("#ext").text("[" + nextPlayObject.Ext + "]" );
  210. currentPlaying = nextPlayObject.Filename;
  211. playVideo("../media?file=" + encodeURIComponent(nextPlayObject.Filepath));
  212. $("#videolist").find(".search").val(nextPlayObject.Filename);
  213. $(".playing").removeClass("playing");
  214. $(".videoObject").each(function(){
  215. if ($(this).attr("filename") + $(this).attr("ext") == nextPlayObject.Filename){
  216. $(this).addClass("playing");
  217. }
  218. });
  219. }
  220. function playPreviousVideo(){
  221. var nextToPlay = 0;
  222. for (var i =0; i < currentPlaylist.length; i++){
  223. if (currentPlaylist[i].Filename == currentPlaying){
  224. nextToPlay = i - 1;
  225. if (nextToPlay < 0){
  226. //First video. Loopback to the final video
  227. nextToPlay = currentPlaylist.length - 1;
  228. }
  229. }
  230. }
  231. //Play the selected item
  232. var nextPlayObject = currentPlaylist[nextToPlay];
  233. if (nextPlayObject == undefined){
  234. //No playlist or no object to play
  235. return;
  236. }
  237. console.log(currentPlaylist[nextToPlay],nextToPlay);
  238. $("#videoname").text(nextPlayObject.Filename);
  239. $("#ext").text("[" + nextPlayObject.Ext + "]" );
  240. currentPlaying = nextPlayObject.Filename;
  241. playVideo("../media?file=" + encodeURIComponent(nextPlayObject.Filepath));
  242. $("#videolist").find(".search").val(nextPlayObject.Filename);
  243. $(".playing").removeClass("playing");
  244. $(".videoObject").each(function(){
  245. if ($(this).attr("filename") + $(this).attr("ext") == nextPlayObject.Filename){
  246. $(this).addClass("playing");
  247. }
  248. });
  249. }
  250. function jumpToPlayingVideo(){
  251. if ($(".videoObject.playing").length == 0){
  252. return;
  253. }
  254. var scrollToLocation = $(".videoObject.playing").offset().top;
  255. $('html, body').animate({
  256. scrollTop: scrollToLocation
  257. }, 200);
  258. }
  259. function jumpToPlayingPlaylist(){
  260. if ($(".playlistObject.active").length == 0){
  261. return;
  262. }
  263. var scrollToLocation = $(".playlistObject.active").offset().top;
  264. $('html, body').animate({
  265. scrollTop: scrollToLocation
  266. }, 200);
  267. }
  268. function setAutoplay(obj){
  269. autoPlay = obj.checked;
  270. if (autoPlay){
  271. ao_module_storage.setStorage("Video","autoplay","true");
  272. }else{
  273. ao_module_storage.setStorage("Video","autoplay","false");
  274. }
  275. }
  276. /*
  277. $("#playListSelector").on("change",function(){
  278. var selectedPlaylistName = $(this).val();
  279. var thisPlaylistDevice = "";
  280. $("#playListSelector").find(".playlistObject").each(function(){
  281. if ($(this).attr("value") == selectedPlaylistName){
  282. thisPlaylistDevice = $(this).attr("device");
  283. }
  284. });
  285. if (thisPlaylistDevice.length == 0){
  286. //Unsorted playlist
  287. console.log("Listing unsorted playlists");
  288. listUnsortedFiles();
  289. }else{
  290. listPlayList(selectedPlaylistName);
  291. }
  292. //console.log(thisPlaylistDevice);
  293. });
  294. */
  295. function selectedPlaylist(object, selectedPlaylistName){
  296. //Hightlight this playlist object
  297. $(".playlistObject.active").removeClass('active');
  298. $(object).addClass("active");
  299. listPlayList(selectedPlaylistName);
  300. $('#playList').accordion('open',1);
  301. }
  302. function setScreenSize(size){
  303. $("#dplayer").css("width",size);
  304. }
  305. function initPlaylist(){
  306. $.ajax({
  307. url: "../system/ajgi/interface?script=Video/backend/buildPlaylist.js",
  308. success: function(data){
  309. console.log(data);
  310. //Initial playlist dropdown
  311. $("#playListSelector").html("");
  312. //$("#playListSelector").append(`<option class="" value="">Select Playlist</option>`);
  313. for (var i = 0; i < data.length; i++){
  314. var thisDevice = data[i];
  315. var thisDeviceName = thisDevice.StorageName;
  316. var playlistInThisDevice = thisDevice.PlayLists;
  317. //var unsortedVideoInThisDevice = thisDevice.UnsortedVideos;
  318. //Append playlist
  319. for (var j = 0; j < playlistInThisDevice.length; j++){
  320. var thisPlaylistName = playlistInThisDevice[j].Name;
  321. var thisPlaylistThumbnail = playlistInThisDevice[j].Thumbnail;
  322. if (thisPlaylistThumbnail == false){
  323. thisPlaylistThumbnail = "img/desktop_icon.png";
  324. }else{
  325. thisPlaylistThumbnail = "data:image/jpg;base64," + thisPlaylistThumbnail;
  326. }
  327. AllPlaylist.push(JSON.parse(JSON.stringify(playlistInThisDevice[j])));
  328. //$("#playListSelector").append(`<option class="playlistObject" value="${thisPlaylistName}" device="${thisDeviceName}">${thisPlaylistName}</option>`);
  329. $("#playListSelector").append(`
  330. <div class="playlistObject item" onclick="selectedPlaylist(this,'${thisPlaylistName}');">
  331. <div class="right floated content">
  332. <div onclick="event.preventDefault(); event.stopImmediatePropagation(); ao_module_openPath('${playlistInThisDevice[j].Folderpath}');" class="ui icon button"><i class="folder open icon"></i></div>
  333. </div>
  334. <img class="ui tiny image " src="${thisPlaylistThumbnail}">
  335. <div class="content" style="margin-top: 1em; max-width: calc(100% - 15em);">
  336. <div class="header">${thisPlaylistName}</div>
  337. <div class="description" style="margin-top: 0.4em;" ><span style="margin-left: 0em;"><i class="file outline icon"></i> x ${playlistInThisDevice[j].Files.length}</span></div>
  338. </div>
  339. </div>
  340. `);
  341. }
  342. /*
  343. for (var k = 0; k < unsortedVideoInThisDevice.length; k++){
  344. unsortedVideoFiles.push(JSON.parse(JSON.stringify(unsortedVideoInThisDevice[k])));
  345. }
  346. */
  347. }
  348. //Append unsorted into playlist
  349. //$("#playListSelector").append(`<option class="playlistObject" value="unsorted" device="">Unsorted Playlist</option>`);
  350. updateWindowEvents();
  351. $("#playList").accordion();
  352. $('#playList').accordion('open',0);
  353. }
  354. });
  355. }
  356. function listPlayList(playlistName){
  357. $("#videolist").html("");
  358. var targetPlaylist;
  359. for (var i =0; i < AllPlaylist.length; i++){
  360. if (AllPlaylist[i].Name == playlistName){
  361. targetPlaylist = AllPlaylist[i];
  362. }
  363. }
  364. currentPlaylist = targetPlaylist.Files;
  365. //Parse the playlist
  366. for (var i = 0; i < currentPlaylist.length; i++){
  367. var playListName = targetPlaylist.Name;
  368. var thisVideoName = currentPlaylist[i].Filename;
  369. thisVideoName = thisVideoName.split(".");
  370. thisVideoName.pop();
  371. thisVideoName = thisVideoName.join(".");
  372. var thisFilePath = currentPlaylist[i].Filepath;
  373. var ext = currentPlaylist[i].Ext;
  374. $("#videolist").append(`<div class="item videoObject" onclick="playThisFile(this);" filename="${thisVideoName}" filepath="${thisFilePath}" ext="${ext}" playlist="${playListName}">
  375. <img class="ui top aligned tiny image thumbnail" src="img/no_preview.svg">
  376. <div class="content" style="width: calc(100% - 100px);">
  377. <p class="header">${thisVideoName}</p>
  378. <div class="description">${thisFilePath} <br> ${ext.substr(1)}</div>
  379. </div>
  380. </div>`);
  381. }
  382. //Render the thumbnail
  383. $(".videoObject").each(function(){
  384. let vidDomElet = $(this);
  385. ao_module_agirun("Video/backend/getThumbnail.js", {
  386. file: $(this).attr("filepath")
  387. },function(data){
  388. if (data.error == undefined && data.length > 0){
  389. //Thumbnail get. Render it to the DOM element
  390. $(vidDomElet).find(".thumbnail").attr("src", 'data:image/jpg;base64,' + data);
  391. }
  392. } );
  393. });
  394. }
  395. function playThisFile(obj){
  396. $(".playing").removeClass("playing");
  397. //var fileDescriptor = $(obj).parent().parent();
  398. var fileDescriptor = $(obj);
  399. $("#videoname").text(fileDescriptor.attr("filename"));
  400. $("#playlistName").text(fileDescriptor.attr("playlist"));
  401. $("#ext").text("[" + fileDescriptor.attr("ext") + "]" );
  402. currentPlaying = fileDescriptor.attr('filename') + fileDescriptor.attr("ext");
  403. playVideo("../media?file=" + encodeURIComponent(fileDescriptor.attr("filepath")));
  404. $(fileDescriptor).addClass("playing");
  405. window.scrollTo(0, 0);
  406. ao_module_setWindowTitle("Video - " + fileDescriptor.attr("filename"));
  407. }
  408. function playVideo(src){
  409. playerObject.video.src = src;
  410. playerObject.play()
  411. updateWindowEvents();
  412. }
  413. $(window).on("resize",function(){
  414. updateWindowEvents();
  415. });
  416. function updateWindowEvents(){
  417. $("#dplayer").css("max-height",window.innerHeight);
  418. }
  419. </script>
  420. </body>
  421. </html>