ttw_fmx_v10/utils/uOBS_Doc_Player.pas

274 lines
8.0 KiB
Plaintext

unit uOBS_Doc_Player;
interface
uses
System.SysUtils, System.Classes, Web.HTTPApp, FMX.Types,
FMX.Controls3D, FMX.Objects3D, FMX.Controls, FMX.Forms, FMX.StdCtrls,
FMX.Edit, FMX.ListBox, uPlayerThread, bass_simple;
type
TOBS_Doc_Player = class(TWebModule)
procedure WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure WebModuleCreate(Sender: TObject);
procedure WebModuleDestroy(Sender: TObject);
private
{ Private declarations }
function gethtml(): string;
procedure AddToListBox(Text: String);
procedure DelFromListBox(Text: String);
procedure add(const aTitle: string);
procedure del(const aTitle: string);
{ Private declarations }
public
{ Public declarations }
end;
var
OBS_Doc_Player: TComponentClass = TOBS_Doc_Player;
Button1: TButton;
Button2: TButton;
ProgressBar1: TProgressBar;
TrackBar1: TTrackBar;
ListBox1: TListBox;
b: TBassSimple;
player: TPlayerThread;
mVolume: Integer;
isplay: string;
mySoundPath: string;
implementation
{%CLASSGROUP 'FMX.Controls.TControl'}
{$R *.dfm}
{ TOBS_Doc_Player }
function GetPathToTestExe: string; // âåðíåò ïàïêó romaming
begin
Result := GetEnvironmentVariable('APPDATA');
if Result <> '' then
Result := IncludeTrailingPathDelimiter(Result);
end;
procedure TOBS_Doc_Player.add(const aTitle: string);
begin
AddToListBox(aTitle);
end;
procedure TOBS_Doc_Player.AddToListBox(Text: String);
begin
if ListBox1.Items.IndexOf(Text) = -1 then
ListBox1.Items.add(Text);
end;
procedure TOBS_Doc_Player.Button1Click(Sender: TObject);
begin
b.Pause;
if isplay = '0' then
isplay := '1'
else
isplay := '0'
end;
procedure TOBS_Doc_Player.Button2Click(Sender: TObject);
begin
player.Skip;
end;
procedure TOBS_Doc_Player.del(const aTitle: string);
begin
DelFromListBox(aTitle);
end;
procedure TOBS_Doc_Player.DelFromListBox(Text: String);
var
i: Integer;
begin
Application.ProcessMessages;
i := ListBox1.Items.IndexOf(Text);
if i <> -1 then
if i <= ListBox1.Items.Count - 1 then
ListBox1.Items.Delete(i);
Application.ProcessMessages;
end;
function TOBS_Doc_Player.gethtml: string;
var
s: string;
i: Integer;
playIcon: string;
begin
// Îïðåäåëÿåì èêîíêó â çàâèñèìîñòè îò ñîñòîÿíèÿ
if isplay = '1' then
playIcon := 'fa-pause'
else
playIcon := 'fa-play';
// Ñîáèðàåì ýëåìåíòû ListBox â ñòðîêó
s := '';
for i := 0 to ListBox1.Items.Count - 1 do
s := s + '<li>' + ListBox1.Items[i] + '</li>';
// Ãåíåðàöèÿ HTML-ñòðàíèöû ñ îáíîâëåííûìè çíà÷åíèÿìè
Result := '<html>' + '<head><title>Web Radio</title>' +
'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">'
+ '<style>' + 'body {' + 'background-color: #1d1f21;' + 'color: #ffffff;' +
'font-family: "Arial", sans-serif;' + 'text-align: center;' + 'margin: 0;' +
'padding: 20px;' + 'display: flex;' + 'flex-direction: column;' +
'align-items: center;' + '}' +
'.controls {' + 'display: flex;' + 'gap: 20px;' + 'align-items: center;' +
'margin: 20px 0;' + '}' +
'.icon-btn {' + 'cursor: pointer;' + 'font-size: 24px;' + 'color: #4e8b31;'
+ 'transition: transform 0.2s, color 0.2s;' + 'background: none;' +
'border: none;' + 'padding: 10px;' + '}' +
'.icon-btn:hover {' + 'color: #5f9c42;' + 'transform: scale(1.1);' + '}' +
'.volume-container {' + 'margin: 20px 0;' + '}' +
'ul {' + 'list-style-type: none;' + 'padding: 0;' + 'color: #ccc;' +
'max-width: 500px;' + 'width: 100%;' + '}' +
'li {' + 'background-color: #333;' + 'margin: 5px;' + 'padding: 15px;' +
'border-radius: 5px;' + 'text-align: left;' + '}' +
'#currentVolume {' + 'font-size: 16px;' + 'color: #ddd;' +
'margin-bottom: 10px;' + '}' + '</style>' +
'<script>' + 'function setVolume(val) {' +
' fetch("/setVolume?value=" + val); ' +
' document.getElementById("currentVolume").innerText = "Ãðîìêîñòü: " + val + "%";'
+ '} ' +
'function btn(val) {' + ' if (val == 1) {' +
' const icon = document.getElementById("playIcon");' +
' icon.classList.toggle("fa-play");' +
' icon.classList.toggle("fa-pause");' + ' fetch("/button1");' + ' }'
+ ' if (val == 2) fetch("/button2");' + '}' + '</script>' + '</head>' +
'<body>' + '<div class="controls">' +
'<i id="playIcon" class="icon-btn fas ' + playIcon +
'" onclick="btn(1)"></i>' +
'<i class="icon-btn fas fa-forward" onclick="btn(2)"></i>' + '</div>' +
'<div class="volume-container">' + '<label id="currentVolume">Ãðîìêîñòü: ' +
IntToStr(mVolume) + '%</label>' +
'<input type="range" min="0" max="100" value="' + IntToStr(mVolume) +
'" onchange="setVolume(this.value)" />' + '</div>' +
'<ul id="songList">' + s + '</ul>' +
'<script>' + 'function updateSongList() {' + ' fetch("/getSongs")' +
' .then(response => response.json())' + ' .then(data => {' +
' const listElement = document.getElementById("songList");' +
' listElement.innerHTML = "";' + ' data.forEach(song => {' +
' const li = document.createElement("li");' +
' li.textContent = song;' + ' listElement.appendChild(li);' +
' });' + ' })' +
' .catch(error => console.error("Error fetching songs:", error));' + '}'
+ 'setInterval(updateSongList, 3000);' + '</script>' + '</body>' +
'</html>';
end;
procedure TOBS_Doc_Player.TrackBar1Change(Sender: TObject);
begin
mVolume := Round(TrackBar1.Value);
b.Volume := mVolume;
end;
procedure TOBS_Doc_Player.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
VolumeStr: string;
VolumeValue, i: Integer;
begin
if Request.PathInfo = '/getSongs' then
begin
// Âîçâðàùàåì ñïèñîê ïåñåí â ôîðìàòå JSON
var
songList: string := '[';
for i := 0 to ListBox1.Items.Count - 1 do
begin
songList := songList + '"' + ListBox1.Items[i] + '"';
if i < ListBox1.Items.Count - 1 then
songList := songList + ',';
end;
songList := songList + ']';
Response.Content := songList; // Îòïðàâëÿåì JSON
Response.ContentType := 'application/json;charset=utf8';
Handled := True;
Exit;
end;
if Request.PathInfo = '/setVolume' then
begin
// Ïîëó÷àåì çíà÷åíèå èç ïàðàìåòðà 'value'
VolumeStr := Request.QueryFields.Values['value'];
// Ïðîáóåì ïðåîáðàçîâàòü â öåëîå ÷èñëî
if TryStrToInt(VolumeStr, VolumeValue) then
begin
// Åñëè óäàëîñü ïðåîáðàçîâàòü, îáíîâëÿåì ïåðåìåííóþ mVolume
mVolume := VolumeValue;
// Îáíîâëÿåì çâóê íà ñåðâåðå (åñëè íóæíî, íàïðèìåð, ÷åðåç áèáëèîòåêó bass)
b.Volume := mVolume;
// Âîçâðàùàåì îáíîâëåííîå ñîñòîÿíèå íà ñòðàíèöó
Response.Content := gethtml;
end
else
begin
// Åñëè íå óäàëîñü ïðåîáðàçîâàòü, âîçâðàùàåì îøèáêó
Response.Content := 'Invalid volume value';
end;
Handled := True; // Çàïðîñ îáðàáîòàí
Exit;
end;
if Request.PathInfo = '/button1' then
begin
Button1Click(Sender); // Âûçîâ ïðîöåäóðû äëÿ êíîïêè 1
Response.Content := gethtml;
Handled := True; // Óêàçûâàåì, ÷òî çàïðîñ áûë îáðàáîòàí
Exit;
end;
if Request.PathInfo = '/button2' then
begin
Button2Click(Sender); // Âûçîâ ïðîöåäóðû äëÿ êíîïêè 2
Response.Content := gethtml;
Handled := True; // Óêàçûâàåì, ÷òî çàïðîñ áûë îáðàáîòàí
Exit;
end;
Response.Content := gethtml;
Handled := True;
end;
procedure TOBS_Doc_Player.WebModuleCreate(Sender: TObject);
begin
mySoundPath := GetPathToTestExe + 'TTW_Bot\ytSongs';
b := TBassSimple.Create(0);
player := TPlayerThread.Create(b, mySoundPath);
player.OnAddAd := add;
player.OnSkip := del;
mVolume := 0;
ListBox1 := TListBox.Create(self);
player.Start;
isplay := '1';
end;
procedure TOBS_Doc_Player.WebModuleDestroy(Sender: TObject);
begin
player.Free;
b.Free;
ListBox1.Free;
end;
end.