main.pas 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. program main;
  2. {$mode objfpc}
  3. uses
  4. browserapp, JS, Classes, SysUtils, Web;
  5. type
  6. TTrack = Record
  7. name,
  8. artist,
  9. image,
  10. path,
  11. display,
  12. url : String;
  13. end;
  14. TMyApplication = class(TBrowserApplication)
  15. now_playing,
  16. track_art,
  17. track_name,
  18. track_artist,
  19. display_text,
  20. playpause_btn,
  21. next_btn,
  22. prev_btn,
  23. curr_time,
  24. total_duration : TJSHTMLElement;
  25. curr_track : TJSHTMLAudioElement;
  26. volume_slider,
  27. seek_slider : TJSHTMLinputElement;
  28. isPlaying : Boolean;
  29. track_index : Integer;
  30. updateTimer: Integer;
  31. Procedure BindElements;
  32. Procedure seekTo(Event: TJSEvent);
  33. Procedure SetVolume(Event: TJSEvent);
  34. Procedure DoPlayPause(Event: TJSEvent);
  35. Procedure NextTrack(Event: TJSEvent);
  36. Procedure PrevTrack(Event: TJSEvent);
  37. Procedure PlayTrack;
  38. Procedure PauseTrack;
  39. procedure LoadTrack(aIndex : Integer);
  40. procedure random_bg_color;
  41. procedure resetValues;
  42. procedure seekUpdate;
  43. procedure doRun; override;
  44. private
  45. end;
  46. var
  47. track_list : Array of TTrack; external name 'track_list';
  48. procedure TMyApplication.seekUpdate;
  49. Var
  50. seekPosition : Double;
  51. currentMinutes,
  52. currentSeconds,
  53. durationMinutes,
  54. durationSeconds : Integer;
  55. begin
  56. if jsIsNan(curr_track.duration) then exit;
  57. seekPosition:=curr_track.currentTime * (100 / curr_track.duration);
  58. seek_slider.value :=FloatToStr(seekPosition);
  59. currentMinutes:=Round(curr_track.currentTime / 60);
  60. currentSeconds:=Round(curr_track.currentTime - currentMinutes * 60);
  61. durationMinutes:=Round(curr_track.duration / 60);
  62. durationSeconds:=Round(curr_track.duration - durationMinutes * 60);
  63. curr_time.innerText:= Format('%.2:%d2',[currentMinutes,currentSeconds]);
  64. total_duration.innerText:=Format('%.2:%d2',[durationMinutes,durationSeconds]);
  65. end;
  66. procedure TMyApplication.BindElements;
  67. Function GetElement (aClass : String) : TJSHTMLELement;
  68. begin
  69. Result:=TJSHTMLELement(Document.querySelector('.'+aClass));
  70. Writeln('Looking for ',aClass,' : ',assigned(Result));
  71. end;
  72. begin
  73. now_playing :=GetElement('now-playing');
  74. track_art :=GetElement('track-art');
  75. track_name :=GetElement('track-name');
  76. track_artist :=GetElement('track-artist');
  77. display_text :=GetElement('display-text');
  78. playpause_btn :=GetElement('playpause-track');
  79. playpause_btn.AddEventListener('click',@DoPlayPause);
  80. next_btn :=GetElement('next-track');
  81. next_btn.AddEventListener('click',@NextTrack);
  82. prev_btn :=GetElement('prev-track');
  83. prev_btn.AddEventListener('click',@PrevTrack);
  84. seek_slider :=TJSHTMLInputElement(GetElement('seek_slider'));
  85. seek_slider.AddEventListener('change',@SeekTo);
  86. volume_slider :=TJSHTMLInputElement(GetElement('volume_slider'));
  87. volume_slider.AddEventListener('change',@SetVolume);
  88. curr_time :=GetElement('current-time');
  89. total_duration :=GetElement('total-duration');
  90. end;
  91. procedure TMyApplication.seekTo(Event: TJSEvent);
  92. Var
  93. dSeekTo : Double;
  94. begin
  95. dSeekTo := curr_track.duration * (StrToFloatDef(seek_slider.value,50) / 100);
  96. curr_track.currentTime := dSeekTo;
  97. end;
  98. procedure TMyApplication.SetVolume(Event: TJSEvent);
  99. begin
  100. curr_track.volume := StrToFloatDef(volume_slider.value,50) / 100;
  101. end;
  102. procedure TMyApplication.DoPlayPause(Event: TJSEvent);
  103. begin
  104. if isPlaying then
  105. pauseTrack
  106. else
  107. playTrack;
  108. end;
  109. procedure TMyApplication.NextTrack(Event: TJSEvent);
  110. begin
  111. // Go back to the first track if the
  112. // current one is the last in the track list
  113. if (track_index < (Length(track_list) - 1)) then
  114. Inc(track_index)
  115. else
  116. track_index:=0;
  117. // Load and play the new track
  118. loadTrack(track_index);
  119. playTrack();
  120. end;
  121. procedure TMyApplication.PrevTrack(Event: TJSEvent);
  122. begin
  123. if (track_index > 0) then
  124. Dec(track_index)
  125. else
  126. track_index := Length(track_list)- 1;
  127. loadTrack(track_index);
  128. playTrack();
  129. end;
  130. procedure TMyApplication.PlayTrack;
  131. begin
  132. curr_track.play();
  133. isPlaying:=true;
  134. playpause_btn.innerHTML := '<i class="fa fa-pause-circle fa-5x"></i>';
  135. end;
  136. procedure TMyApplication.PauseTrack;
  137. begin
  138. curr_track.pause();
  139. isPlaying:=false;
  140. playpause_btn.innerHTML := '<i class="fa fa-play-circle fa-5x"></i>';
  141. end;
  142. procedure TMyApplication.LoadTrack(aIndex: Integer);
  143. begin
  144. // Clear the previous seek timer
  145. window.clearInterval(updateTimer);
  146. resetValues();
  147. curr_track.src :=track_list[track_index].path;
  148. curr_track.load();
  149. track_art.style.SetProperty('background-image','url("' + track_list[track_index].image+ '")');
  150. track_art.style.SetProperty('background-image','url("' + track_list[track_index].image+ '")');
  151. track_artist.InnerHTML := track_list[track_index].artist;
  152. track_name.InnerHTML := track_list[track_index].name;
  153. display_text.InnerHTML:=String(track_list[track_index].display);
  154. now_playing.InnerHTML := Format('PLAYING %d OF %d',[track_index + 1,Length(track_list)]);
  155. updateTimer :=Window.setInterval(@seekUpdate, 1000);
  156. curr_track.addEventListener('ended', @nextTrack);
  157. random_bg_color();
  158. end;
  159. procedure TMyApplication.random_bg_color;
  160. Const
  161. Lim = 256 - 64;
  162. Var
  163. red,Green,blue : Integer;
  164. col : string;
  165. begin
  166. red:=Round(random(Lim) + 64);
  167. green:=Round(random(lim) + 64);
  168. blue:=Round(random(lim)+64);
  169. col:= Format('rgb(%d,%d,%d)',[red, green ,blue]);
  170. TJSHTMLELement(document.body).style.SetProperty('background',col);
  171. end;
  172. procedure TMyApplication.resetValues;
  173. begin
  174. curr_time.InnerHTML:= '00:00';
  175. total_duration.InnerHTML:= '00:00';
  176. seek_slider.value:='0';
  177. end;
  178. procedure TMyApplication.doRun;
  179. begin
  180. Terminate;
  181. BindElements;
  182. curr_track:=TJSHTMLAudioElement(document.createElement('audio'));
  183. curr_track.autoplay:=true;
  184. ResetValues;
  185. Window.SetInterval(@seekUpdate,1000);
  186. LoadTrack(0);
  187. end;
  188. var
  189. Application : TMyApplication;
  190. begin
  191. Application:=TMyApplication.Create(nil);
  192. Application.Initialize;
  193. Application.Run;
  194. end.