📄 u_icy_client.pas
字号:
(*
----------------------------------------------
u_icy_client.pas
Icy Streaming Client Demo application - main form
----------------------------------------------
This source code cannot be used without
proper license granted to you as a private
person or an entity by the Lake of Soft, Ltd
Visit http://lakeofsoft.com/ for more information.
Copyright (c) 2001, 2007 Lake of Soft, Ltd
All rights reserved
----------------------------------------------
created by:
Lake, 19 May 2003
modified by:
Lake, May-Dec 2003
Lake, Mar 2004
Lake, Oct 2005
Lake, Feb 2006
----------------------------------------------
*)
{$I unaDef.inc}
{$I unaBassDef.inc }
unit
u_icy_client;
interface
uses
Windows, unaTypes, Forms, unaClasses,
unaMsAcmClasses, unaMpglibAPI, unaEncoderAPI, unaIcyStreamer,
Controls, StdCtrls, ComCtrls, ExtCtrls, Classes, ActnList;
type
// -- --
Tc_form_main = class(TForm)
c_statusBar_main: TStatusBar;
c_timer_main: TTimer;
c_actionList_main: TActionList;
a_str_start: TAction;
a_str_stop: TAction;
a_lst_start: TAction;
a_lst_stop: TAction;
a_str_push: TAction;
c_pageControl_main: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
c_label_strStatus: TLabel;
Label13: TLabel;
c_label_encoderInfo: TLabel;
c_button_strStart: TButton;
c_button_strStop: TButton;
c_edit_songTitle: TEdit;
Button1: TButton;
c_checkBox_autoPush: TCheckBox;
c_label_lstStatus: TLabel;
c_label_decoderInfo: TLabel;
c_button_lstStart: TButton;
c_button_lstStop: TButton;
TabSheet3: TTabSheet;
TabSheet4: TTabSheet;
Label14: TLabel;
c_comboBox_srvType: TComboBox;
Label1: TLabel;
c_edit_host: TEdit;
c_edit_port: TEdit;
Label11: TLabel;
Label3: TLabel;
c_edit_password: TEdit;
Bevel1: TBevel;
Bevel2: TBevel;
c_label_strInfo: TLabel;
Button2: TButton;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Button3: TButton;
c_label_lstInfo: TLabel;
a_lst_config: TAction;
a_str_config: TAction;
Label2: TLabel;
c_edit_songURL: TEdit;
c_memo_streamInfo: TMemo;
Bevel3: TBevel;
Bevel4: TBevel;
Bevel5: TBevel;
Bevel6: TBevel;
c_edit_listenerURL: TEdit;
Label12: TLabel;
//
procedure formCreate(sender: tObject);
procedure formCloseQuery(sender: tObject; var canClose: boolean);
procedure formShow(sender: tObject);
//
procedure c_timer_mainTimer(Sender: TObject);
procedure c_checkBox_autoPushClick(Sender: TObject);
//
procedure a_str_configExecute(Sender: TObject);
procedure a_lst_configExecute(Sender: TObject);
procedure a_str_startExecute(Sender: TObject);
procedure a_str_stopExecute(Sender: TObject);
procedure a_str_pushExecute(Sender: TObject);
procedure a_lst_startExecute(Sender: TObject);
procedure a_lst_stopExecute(Sender: TObject);
//
procedure urlLabelClick(Sender: TObject);
private
{ Private declarations }
f_config: unaIniFile;
//
f_provider: unaIcyStreamProvider;
f_consumer: unaIcyStreamConsumer;
//
f_waveIn: unaWaveInDevice;
f_aiutoPushCountdown: int;
//
f_lame: unaLameMp3Enc;
f_lameError: int;
//
f_waveOut: unaWaveOutDevice;
f_bass: unaBass;
f_bassStream: unaBassStream;
f_bassError: int;
f_dataStream: unaMemoryStream;
f_bassStreamThread: unaBassStreamDecoder;
//
f_mpgDecoder: unaMpgLibDecoder;
//
f_dataOutSize: int64;
f_dataInSize: int64;
//
procedure updateStrConfigInfo();
procedure updateLstConfigInfo();
//
procedure encoderDataAvail(sender: tObject; data: pointer; size: unsigned; var copyToStream: bool);
procedure consumerDataAvail(sender: tObject; data: pointer; size: unsigned);
procedure configLame(bitRate, samplingRate: unsigned; stereo: bool);
procedure waveDataAvail(sender: tObject; data: pointer; size: unsigned);
public
{ Public declarations }
//
strSource: int;
strSourceIndex: int;
strSourcePath: string;
strEncoder: string;
strBitrate: int;
strStereo: bool;
strTitle: string;
strURL: string;
strGenre: string;
strAllowPublishing: bool;
//
lstDestination: int;
lstDestPath: string;
lstDecoder: string;
//
property config: unaIniFile read f_config;
end;
var
c_form_main: Tc_form_main;
implementation
{$R *.dfm}
uses
unaUtils, SysUtils, MMSystem, ShellAPI,
unaVCLUtils, unaBladeEncAPI, unaBassAPI,
u_icy_clientStreamConfig, u_icy_clientListenConfig;
type
//
// -- localBassStreamDecoder --
//
localBassStreamDecoder = class(unaBassStreamDecoder)
protected
procedure applySampling(rate, bits, channels: unsigned); override;
procedure dataAvailable(data: pointer; size: unsigned); override;
public
constructor create();
end;
//
// -- tMpgLibDecoder --
//
localMpgLibDecoder = class(unaMpgLibDecoder)
protected
procedure notifyData(data: pointer; size: unsigned; var copyToStream: bool); override;
procedure notifySamplingChange(rate, bits, channels: unsigned); override;
end;
{ localBassStreamDecoder }
// -- --
procedure localBassStreamDecoder.applySampling(rate, bits, channels: unsigned);
begin
with (c_form_main.f_waveOut) do begin
//
close();
setSampling(rate, bits, channels);
open();
end;
end;
// -- --
constructor localBassStreamDecoder.create();
begin
inherited create(c_form_main.f_bassStream, c_form_main.f_dataStream, 20000); // 20 sec timeout for TCP data should be enough
end;
// -- --
procedure localBassStreamDecoder.dataAvailable(data: pointer; size: unsigned);
begin
with (c_form_main.f_waveOut) do begin
//
if (isOpen()) then
write(data, size);
end;
end;
{ localMpgLibDecoder }
// -- --
procedure localMpgLibDecoder.notifyData(data: pointer; size: unsigned; var copyToStream: bool);
begin
inherited;
//
with (c_form_main.f_waveOut) do begin
//
if (isOpen()) then
write(data, size);
end;
end;
// -- --
procedure localMpgLibDecoder.notifySamplingChange(rate, bits, channels: unsigned);
begin
inherited;
//
with (c_form_main.f_waveOut) do begin
close();
setSampling(rate, bits, channels);
open();
end;
end;
{ Tc_form_main }
// -- --
procedure Tc_form_main.formCreate(sender: tObject);
begin
f_config := unaIniFile.create();
f_provider := unaIcyStreamProvider.create('', '');
f_consumer := unaIcyStreamConsumer.create('', '');
f_consumer.onDataAvailable := consumerDataAvail;
//
f_waveIn := unaWaveInDevice.create(WAVE_MAPPER, false, false, 10);
f_waveIn.onDataAvailable := waveDataAvail;
//
f_waveOut := unaWaveOutDevice.create(WAVE_MAPPER, false, false, 1000{SHOUTcast loves to buffer much of data});
f_dataStream := unaMemoryStream.create();
f_dataStream.maxCacheSize := 100;
end;
// -- --
procedure Tc_form_main.formShow(sender: tObject);
begin
loadControlPosition(self, f_config);
//
c_comboBox_srvType.itemIndex := f_config.get('srv.type', unsigned(0));
c_edit_host.text := f_config.get('srv.address', '192.168.1.1');
c_edit_port.text := f_config.get('srv.port', '8000');
c_edit_password.text := f_config.get('srv.pass', 'hackme');
c_edit_listenerURL.text := f_config.get('lst.url', '/');
c_edit_songTitle.text := f_config.get('str.songTitle', 'Live recording');
//
strSource := f_config.get('str.source', unsigned(0));
strSourceIndex := f_config.get('str.sourceIndex', unsigned(0));
strSourcePath := f_config.get('str.sourcePath', '');
strEncoder := f_config.get('str.encoder', 'Lame_Enc.Dll');
strBitrate := f_config.get('str.bitrate', unsigned(128));
strStereo := f_config.get('str.stereo', true);
strTitle := 'VC 2.5 Streamer';
//strTitle := f_config.get('str.title', 'VC 2.5 Streamer');
strURL := f_config.get('str.URL', 'http://lakeofsoft.com/vc/');
strGenre := f_config.get('str.genre', 'Rock');
strAllowPublishing := f_config.get('str.allowPublishing', false);
//
lstDestination := f_config.get('lst.destination', unsigned(0));
lstDestPath := f_config.get('lst.destPath', '');
lstDecoder := f_config.get('lst.decoder', 'Bass.Dll');
//
{$IFDEF __AFTER_D4__ }
c_pageControl_main.activePageIndex := f_config.get('gui.tabIndex', int(0));
{$ENDIF}
//
updateStrConfigInfo();
updateLstConfigInfo();
//
c_timer_main.enabled := true;
end;
// -- --
procedure Tc_form_main.formCloseQuery(sender: tObject; var canClose: boolean);
begin
c_timer_main.enabled := false;
//
a_str_stop.execute();
a_lst_stop.execute();
//
saveControlPosition(self, f_config);
//
f_config.setValue('srv.type', c_comboBox_srvType.itemIndex);
f_config.setValue('srv.address', c_edit_host.text);
f_config.setValue('srv.port', c_edit_port.text);
f_config.setValue('srv.pass', c_edit_password.text);
f_config.setValue('lst.url', c_edit_listenerURL.text);
//
f_config.setValue('str.source', strSource);
f_config.setValue('str.sourceIndex', strSourceIndex);
f_config.setValue('str.sourcePath', strSourcePath);
f_config.setValue('str.encoder', strEncoder);
f_config.setValue('str.bitrate', strBitrate);
f_config.setValue('str.stereo', strStereo);
f_config.setValue('str.title', strTitle);
f_config.setValue('str.URL', strURL);
f_config.setValue('str.genre', strGenre);
f_config.setValue('str.allowPublishing', strAllowPublishing);
f_config.setValue('str.songTitle', c_edit_songTitle.text);
//
f_config.setValue('lst.destination', lstDestination);
f_config.setValue('lst.destPath', lstDestPath);
f_config.setValue('lst.decoder', lstDecoder);
//
//
{$IFDEF __AFTER_D4__ }
f_config.setValue('gui.tabIndex', c_pageControl_main.activePageIndex);
{$ENDIF}
//
freeAndNil(f_waveIn);
freeAndNil(f_lame);
//
freeAndNil(f_bassStreamThread);
freeAndNil(f_bassStream);
freeAndNil(f_bass);
//
freeAndNil(f_mpgDecoder);
//
freeAndNil(f_dataStream);
freeAndNil(f_waveOut);
//
freeAndNil(f_provider);
freeAndNil(f_consumer);
freeAndNil(f_config);
end;
// -- --
procedure Tc_form_main.c_timer_mainTimer(Sender: TObject);
var
subStrStr: string;
subStrLst: string;
streamInfo: string;
//
kbps, genre, name, url: string;
begin
c_statusBar_main.panels[0].text := int2str(ams() shr 10, 10, 3) + ' KB';
//
subStrStr := '';
subStrLst := '';
case (f_provider.status) of
iss_disconnected: begin
//
if (not a_str_start.enabled and a_str_stop.enabled) then
a_str_stop.execute();
end;
iss_connected: begin
//
subStrStr := ', sent ' + int2str(f_dataOutSize, 10, 3) + ' bytes.';
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -