Cześć.
Mam do Was pytanie. Delphi a obsługa radia. Chodzi mi o radio internetowe tylko o odbiór. Aby użytkownik mógł wybrać ze cztery stacje które będą określone w programie i mógł ich słuchać. Pisałem tylko bazy o takich rzeczach nie mam zielonego pojęcia. Do Was pytanie? Proszę z grubsza w punktach czego będę potrzebował by taki cel osiągnąć i bardziej ściślej o punkcie pierwszym, jakie komponenty wszystko co możecie mi przekazać by zrealizować punkt pierwszy.
Nie mam o tym pojęcia może to tylko okaże się wpisanie adresu i po sprawie, proszę Was o rozjaśnienie mi sytuacji.
z góry Dziękuję i życzę Wam udanej majówki
https://www.un4seen.com jak sobie ściągniesz paczkę to tam masz przykład dla delphi - netradio
- działa
Mógłbyś zerknąć na to bo szukałem już pięć razy i żeby nie przeoczyć wpisywałem znajdź na stronie radio i nic na żadnej, jakiś rzut zrobić cokolwiek, głupio mi pytać o to ale serio nie widzę
@abrakadaber miał na myśli bibliotekę BASS https://www.un4seen.com/download.php?bass24
Oj dziękuję po podpowiedzi znalazłem :)
Moglibyście mi to pomóc ogarnąć chodzi mi o przykład zamieszczony by go przetestować, było w nim kilka błędów co mogłem ogarnąłem zostały jeszcze dwa
// Incompatible types: 'Pointer' and 'TCaption'
BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, ed_ProxyServer.Text) // set proxy server
// Missing operator or semicolon
cthread := BeginThread(nil, 0, @OpenURL, PAnsiChar(urls[TButton(Sender).Tag]), 0, ThreadId);
A oto całość
procedure TForm1.Button1Click(Sender: TObject);
var
ThreadId: Cardinal;
begin
if (cthread <> 0) then
MessageBeep(0)
else
begin
if cbDirectConnection.Checked then
BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, nil) // disable proxy
else
BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, ed_ProxyServer.Text) // set proxy server
// open URL in a new thread (so that main thread is free)
cthread := BeginThread(nil, 0, @OpenURL, PAnsiChar(urls[TButton(Sender).Tag]), 0, ThreadId);
end;
end;
function OpenURL(url: PWideChar): Integer;
begin
//tu bez zmian
end;
procedure TForm1.Button1Click(Sender: TObject);
var
ThreadId: Cardinal;
begin
if (cthread <> 0) then
MessageBeep(0)
else
begin
if cbDirectConnection.Checked then
BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, nil) // disable proxy
else
BASS_SetConfigPtr(BASS_CONFIG_NET_PROXY, PWideChar(ed_ProxyServer.Text)); // set proxy server
// open URL in a new thread (so that main thread is free)
cthread := BeginThread(nil, 0, @OpenURL, PWideChar(urls[TButton(Sender).Tag]), 0, ThreadId);
end;
end;
idzie mi to jak po grudzie by ten przykład odpalić, Nie ma już błędów DZIĘKUJĘ, ale jak z poziomu Delphi daję Run
to kompiluje ale nic się nie dzieję. CTRL + F12
Sprawdzam czy jest Unit z biblioteką jest(chociaż to raczej logiczne inaczej same błędy by były) ale sprawdzam dlatego gdyż jak odpalam przez plik .exe
wyświetla komunikat Nie można uruchomić programu ponieważ na komputerze nie znaleziono bass.dll spróbuj ponownie..... Co jeszcze mogę z tym zrobić, wybaczcie to moje pierwsze podejście do tego
Biblioteka bass.dll musi być tam gdzie exe.
Teraz działa Dziękuję Wam Bardzo :)
Wyszło mi coś takiego, możecie się przyjrzeć i ewentualnie to lepiej poskładać. Siadłem do lektury i staram się samemu ale to dla mnie czarna magia, Adres radia jest skopiowany z netradio a nie wszystkie tam działały ale jakieś działały więc kopiowałem po kolei jeden za drugim ale nic się nie dzieje, błędów nie wywala kompilator, program się odpala,. Nie wiem czy ja mam błąd w kodzie? czy wadliwy adres? czy czegoś nie zrobiłem?. Żeby dalej się zagłębiać w temat muszę jakoś uruchomić podstawową funkcjonalność czyli uruchomić Play, proszę pomóżcie mi to uruchomić
channel : cardinal;
implementation
{$R *.dfm}
procedure TForm1.btnplayClick(Sender: TObject);
begin
BASS_init(-1,4410,0,Handle,nil);
BASS_SetConfig(BASS_Config_Net_Playlist,1);
channel:=BASS_StreamCreateURL('http://icecast.timlradio.co.uk/a8160.ogg',0,0,nil,0);
BASS_ChannelPlay(chan, false);
end;
procedure TForm1.btnStopClick(Sender: TObject);
begin
if chan <> 0 then
begin
bass_channelstop(channel);
chan:=0;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
BASS_init(-1, 44100, 0, Handle, nil);
BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
BASS_Free;
end;
procedure TForm1.btnPlayClick(Sender: TObject);
begin
channel:= BASS_StreamCreateURL('http://www.radioparadise.com/m3u/mp3-128.m3u', 0,
BASS_STREAM_BLOCK or BASS_UNICODE, nil, 0);
BASS_ChannelPlay(channel, false);
end;
procedure TForm1.btnStopClick(Sender: TObject);
begin
if channel <> 0 then
begin
BASS_ChannelStop(channel);
channel:=0;
end;
end;
Wymiatasz D Z I Ę K U J Ę
Niestety mam jeszcze jedno pytanie bo do tego szybko nie dojdę sam bez waszej pomocy. Miałem przed chwilą taką sytuację - przekładałem laptopa między pokojami i odpiąłem HDMI no i czasem tak mam że dźwięk się w systemie wysypie ale to nie problem. Lecz między czasie odpaliłem ten projekt a tu zdziwienie daje play i zonk - program się wiesza, szukam o co chodzi pierwsze to pisze ten kod od nowa, nie pomaga, odpalam czy mam dźwięk, media windows playera miałem pod ręką, odpalam pierwsze lepsze i już znam przyczynę problemu - brak dźwięku, posypał się przez wypięcie HDMI. Jak się przed tym zabezpieczyć w tym programie, jeśli mógłby ktoś poświęcić swój czas i pomóc bo do tego samemu jeszcze długo nie dojdę. Próbuję samemu też działać jak widzieliście ale tutaj sobie nie poradzę bez Was z góry dziękuję
[...] posypał się przez wypięcie HDMI. Jak się przed tym zabezpieczyć w tym programie [...]
Nijak. Jeśli wypięcie przewodu HDMI crashuje dźwięk w całym systemie to przyczyna leży na poziomie sprzętu, sterowników lub samego systemu. Tak mi się przynajmniej wydaje. Co innego, gdyby tylko Twój program tracił dźwięk, ale jak widać tak nie jest.
Zdrowo myśląc masz zdecydowanie rację i tu nie ma dyskusji. Tylko windows media player odtwarzając plik dźwiękowy pokaże informacje iż napotkał problem z odtworzeniem ale się nie po sypie . A mnie się wiesza i po chwili kończy pracę. To radio to ma być dodatek i praca nad sobą by poznać coś nowego. Ale jak on mi tak będzie crashował i zamknie mi dane w programie to będzie katastrofa. Jak tu zrobić solidny wyjątek i zabezpieczyć się przed tym.
A ten sprawdzałeś czy ten przykładowy kod, który jest razem z biblioteką nie reaguje na to? On ma kontrole statusu to może czasem reagować i w ten sposób przechwycić taki błąd.
Nie tamtego kodu z biblioteką nie sprawdzałem, nie wpadłem na to
Tamten kod to mnie przeraża ja muszę od podstaw coś zrobić a nie gotowca w klejąc o którym nie mam pojęcia.
Do szczęścia to tylko potrzebuję, ogarnąć - czy po clicku się łączy czy nie coś ala conecting i to mi wystarczy, a całe metadane to zbędny bajer jak na teraz. No i ten nieszczęsny crash tu coś muszę wymyśleć.
Aha czyli nie musisz reagować na przerwę w trakcie odtwarzania tylko sprawdzić czy w ogóle udało rozpocząć odtwarzanie? Jeżeli tak to nie ma problemu:
procedure TForm1.btnStartClick(Sender: TObject);
var
err: Integer;
begin
channel:= BASS_StreamCreateURL('http://www.radioparadise.com/m3u/mp3-128.m3u', 0,
BASS_STREAM_BLOCK or BASS_UNICODE, nil, 0);
if channel <> 0 then
BASS_ChannelPlay(channel, false);
err:= Bass_ErrorGetCode();
if err <> 0 then
begin
ShowMessage('Error #' + IntToStr(err));
end;
end;
Oczywiście powinieneś to lepiej oprogramować tak aby podać w błąd w czytelnej postaci. Masz listę numerów błędów zwracanych przez funkcję BASS_ErrorGetCode
na podstawie, której możesz oprogramować czytelne dla użytkownika komunikaty.
Dałeś mi niezła rozkminkę pisząc tylko o reagowaniu na sytuację przy starcie. Wtedy bardziej mi chodziło najpierw o monit że się łączy z radiem, o wykrycie tego procesu, ze faktycznie łączy- tak jak z telefonem słyszysz sygnał jak dzwonisz do kogoś, to tak program jak usłyszy taki sygnał to w tedy monit w Label Conecting... (wybacz mogę mylić pojęcia i prawa tym rządzące) a wszystko moja wina, bo zaczynam nowy etap i startuje jakby od zera. To całkiem inna bajka, jakby z photoshopa przejść na rysowanie rastrem w Corelu czy Ilustratorze, niby to grafika i to ale zupełnie inna. O to wcześniej mi chodziło. I wtedy dopiero błędy dlaczego się nie łączy. Najpierw wychwycić ten moment ze się łączy że coś się dzieje w tym kierunku. No a co do rozkminki i reagowanie by już w trakcie odtwarzania reagować na przerwę w odtwarzaniu to znalazłem coś takiego co wyczytałem łamanym angielskim z dokumentacji że tego będę potrzebował:
BASS_ChannelIsActive
może być użyty do sprawdzenia, czy odtwarzanie jest zablokowane.
BASS_StreamGetFilePosition sprawdzamy Postępy w pobieraniu plików chociaż nie wiem czy mi to potrzebne,
BASS_ChannelSetSync, muszę ustawić za pośrednictwem BASS_SYNC_STALL aby monitorować stan odtwarzania.
Prośba do Ciebie pomógł byś mi ten proces czy jak to nazwać fachowo wychwycić ż tym łączeniem bo nie wiem jak to ugryźć ze jak zacznie się łączyć to w Label napis a jak nie w tedy te błędy , z drugim to zależy od Ciebie czy masz na tyle czasu i chęci, ale czy chociaż czy idę w dobrym kierunku?
BASS_ChannelIsActive
sprawdzisz czy radio odtwarza (nie pauza albo np. bufforowanie) tylko ze mam obawy czy to zareaguje na błąd o którym piszesz. Powinna zwrócić BASS_ACTIVE_STOPPED
ale oczywiście dodatkowo musisz sprawdzać za pomocą jakiejś zmiennej czy to nie użytkownik celowo zatrzymał odtwarzanie. No ale to musisz sam sprawdzić trzeba wątek (nawet prościutki anonymous thread się nada) i w nim sprawdzać (pętla z jakimś małym Sleep
może Sleep(500);
) tyle ze nawet jak ta funkcja zareaguje to nie wiem skąd wziąć informacje o się stało, być może próba ponownego wywołania BASS_ChannelPlay
a po tym BASS_ErrorGetCode
by tutaj pomogła. W każdym razie pierwsze musisz sprawdzić czy BASS_ChannelIsActive
reaguje na taki błąd, ja choćbym chciał to nie sprawdzę bo nie umiem u siebie odtworzyć takiego błędu.
Cześć. na razie zostawiłem obsługę błędów gdyż próbowałem wyciągnąć dane meta z oryginalnego netradio. Po wielu próbach wyszło mi coś takiego(poniżej) działać, działa pokazuje się nazwa wykonawcy wraz z nazwą utworu ale się nie odświeża Label(wiem że tu nie ma prawa ale nie wiem jak to rozgryźć) pewnie szło to też napisać lepiej. Jakbyście mieli czas się przyjrzeć i pomóc w poprawieniu
procedure TForm1.Button1Click(Sender: TObject);
var
p, err: Integer;
meta: PAnsiChar;
begin
channel := BASS_StreamCreateURL('http://www.radioparadise.com/m3u/mp3-128.m3u', 0,
BASS_STREAM_BLOCK or BASS_UNICODE, nil, 0);
if channel <> 0 then
BASS_ChannelPlay(channel, false);
begin
meta := BASS_ChannelGetTags(channel, BASS_TAG_META);
if (meta <> nil) then
begin
p := Pos('StreamTitle=', String(AnsiString(meta)));
if (p = 0) then
Exit;
p := p + 13;
meta := PAnsiChar(AnsiString(Copy(meta, p, Pos(';', String(meta))
- p - 1)));
Label1.caption := meta;
end;
end;
err := Bass_ErrorGetCode();
if err <> 0 then
begin
ShowMessage('Error #' + IntToStr(err));
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label1.Refresh;
end;
Resztę poniżej pozostawiłem bez zmian:
var
channel : cardinal;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
BASS_init(-1, 44100, 0, Handle, nil);
BASS_SetConfig(BASS_CONFIG_NET_PLAYLIST, 1);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if channel <> 0 then
begin
BASS_ChannelStop(channel);
channel:=0;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
BASS_Free;
end;
w Timer1Timer
musisz mieć pobieranie danych meta zamiast Label1.Refresh;
. Pobieranie danych meta czyli ten kawałek
meta := BASS_ChannelGetTags(channel, BASS_TAG_META);
if (meta <> nil) then
begin
p := Pos('StreamTitle=', String(AnsiString(meta)));
if (p = 0) then
Exit;
p := p + 13;
meta := PAnsiChar(AnsiString(Copy(meta, p, Pos(';', String(meta))
- p - 1)));
Label1.caption := meta;
end;