Main.pas 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. unit Main;
  2. (*********************************************************************
  3. * The contents of this file are used with permission, subject to *
  4. * the Mozilla Public License Version 1.1 (the "License"); you may *
  5. * not use this file except in compliance with the License. You may *
  6. * obtain a copy of the License at *
  7. * http://www.mozilla.org/MPL/MPL-1.1.html *
  8. * *
  9. * Software distributed under the License is distributed on an *
  10. * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or *
  11. * implied. See the License for the specific language governing *
  12. * rights and limitations under the License. *
  13. * *
  14. * (C) 2004 Martin Offenwanger: coder@dsplayer.de *
  15. *********************************************************************)
  16. {
  17. @author(Martin Offenwanger: coder@dsplayer.de)
  18. @created(Apr 22, 2004)
  19. @lastmod(May 13, 2005)
  20. }
  21. interface
  22. uses
  23. Windows, Messages, SysUtils, Graphics, Controls, Forms, Dialogs, DirectShow9,
  24. ActiveX, StdCtrls, DSUtil, ExtCtrls, ComCtrls, Buttons, TabNotBk, Classes,
  25. XPMan, Definitions, Filter;
  26. type
  27. TForm1 = class(TForm, IAsyncExCallBack)
  28. PageControl1: TPageControl;
  29. TabSheet2: TTabSheet;
  30. TabSheet3: TTabSheet;
  31. CheckBox1: TCheckBox;
  32. GroupBox2: TGroupBox;
  33. GroupBox3: TGroupBox;
  34. GroupBox4: TGroupBox;
  35. GroupBox5: TGroupBox;
  36. GroupBox6: TGroupBox;
  37. GroupBox7: TGroupBox;
  38. GroupBox8: TGroupBox;
  39. GroupBox9: TGroupBox;
  40. Button6: TButton;
  41. RadioButton3: TRadioButton;
  42. RadioButton4: TRadioButton;
  43. Label7: TLabel;
  44. Label2: TLabel;
  45. Label8: TLabel;
  46. Label3: TLabel;
  47. TrackBar1: TTrackBar;
  48. TrackBar2: TTrackBar;
  49. Label20: TLabel;
  50. Label21: TLabel;
  51. Label22: TLabel;
  52. Label23: TLabel;
  53. Label24: TLabel;
  54. Label25: TLabel;
  55. Label26: TLabel;
  56. Label27: TLabel;
  57. Label16: TLabel;
  58. Label17: TLabel;
  59. Label18: TLabel;
  60. Label19: TLabel;
  61. Label5: TLabel;
  62. Label6: TLabel;
  63. Label4: TLabel;
  64. Label10: TLabel;
  65. Label11: TLabel;
  66. Edit4: TEdit;
  67. ListBox1: TListBox;
  68. TmrCloseApp: TTimer;
  69. TmrNilAll: TTimer;
  70. TmrOpenUrl: TTimer;
  71. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  72. procedure FormCreate(Sender: TObject);
  73. procedure TrackBar1Change(Sender: TObject);
  74. procedure Button6Click(Sender: TObject);
  75. procedure CheckBox1Click(Sender: TObject);
  76. procedure TrackBar2Change(Sender: TObject);
  77. procedure TmrNilAllTimer(Sender: TObject);
  78. procedure ListBox1DblClick(Sender: TObject);
  79. procedure TmrOpenUrlTimer(Sender: TObject);
  80. procedure TmrCloseAppTimer(Sender: TObject);
  81. private
  82. m_ripdir: string;
  83. m_BTAsycEx: IBaseFilter;
  84. m_GraphBuilder: IGraphBuilder;
  85. m_MediaControl: IMediaControl;
  86. m_Mp3Dec: IBaseFilter;
  87. m_BTAsyncExControl: IAsyncExControl;
  88. m_Mpeg1Splitter: IBaseFilter;
  89. m_Pin: IPin;
  90. procedure NilAll();
  91. procedure OpenURL();
  92. procedure refreshripstream();
  93. function AsyncExFilterState(Buffering: LongBool; PreBuffering: LongBool;
  94. Connecting: LongBool; Playing: LongBool;
  95. BufferState: integer): HRESULT; stdcall;
  96. function AsyncExICYNotice(IcyItemName: PChar;
  97. ICYItem: PChar): HRESULT; stdcall;
  98. function AsyncExMetaData(Title: PChar; URL: PChar): HRESULT; stdcall;
  99. function AsyncExSockError(ErrString: PChar): HRESULT; stdcall;
  100. public
  101. end;
  102. var
  103. Form1: TForm1;
  104. const
  105. CLSID_Mpeg1Split: TGUID = '{336475D0-942A-11CE-A870-00AA002FEAB5}';
  106. CLSID_Mp3Dec: TGUID = '{38BE3000-DBF4-11D0-860E-00A024CFEF6D}';
  107. implementation
  108. {$R *.dfm}
  109. procedure TForm1.NilAll();
  110. begin
  111. if Assigned(m_MediaControl) then
  112. m_MediaControl.Stop;
  113. if Assigned(m_BTAsyncExControl) then begin
  114. m_BTAsyncExControl.FreeCallback;
  115. m_BTAsyncExControl := nil;
  116. end;
  117. ListBox1.Enabled := false;
  118. Button6.Enabled := false;
  119. if Assigned(m_BTAsycEx) then
  120. m_BTAsycEx := nil;
  121. ListBox1.Enabled := true;
  122. Button6.Enabled := true;
  123. if Assigned(m_Pin) then
  124. m_Pin := nil;
  125. if Assigned(m_MediaControl) then
  126. m_MediaControl := nil;
  127. if Assigned(m_GraphBuilder) then
  128. m_GraphBuilder := nil;
  129. button6.Caption := 'connect';
  130. end;
  131. procedure TForm1.OpenURL();
  132. begin
  133. button6.Caption := 'disconnect';
  134. CheckDSError(CoCreateInstance(TGUID(CLSID_FilterGraph), nil, CLSCTX_INPROC,
  135. TGUID(IID_IGraphBuilder), m_GraphBuilder));
  136. CheckDSError(m_GraphBuilder.QueryInterface(IID_IMediaControl, m_MediaControl));
  137. m_BTAsycEx := TAsyncEx.Create;
  138. CheckDSError(CoCreateInstance(CLSID_Mp3Dec, nil, CLSCTX_INPROC,
  139. IID_IBaseFilter, m_Mp3Dec));
  140. CheckDSError(CoCreateInstance(CLSID_Mpeg1Split, nil, CLSCTX_INPROC,
  141. IID_IBaseFilter, m_Mpeg1Splitter));
  142. CheckDSError(m_GraphBuilder.AddFilter(m_Mpeg1Splitter, 'MPEG1 Splitter'));
  143. CheckDSError(m_BTAsycEx.QueryInterface(IID_IAsyncExControl,
  144. m_BTAsyncExControl));
  145. if assigned(m_BTAsyncExControl) then
  146. if failed(m_BTAsyncExControl.SetCallBack(self)) then begin
  147. exit;
  148. end;
  149. refreshripstream();
  150. if assigned(m_BTAsyncExControl) then begin
  151. if RadioButton3.Checked then
  152. if failed(m_BTAsyncExControl.SetConnectToURL(PChar(ListBox1.Items[ListBox1.ItemIndex]), TrackBar1.Position * 1000, true)) then begin
  153. exit;
  154. end;
  155. if RadioButton4.Checked then
  156. if failed(m_BTAsyncExControl.SetConnectToURL(PChar(ListBox1.Items[ListBox1.ItemIndex]), TrackBar1.Position * 1000, false)) then begin
  157. exit;
  158. end;
  159. end;
  160. if assigned(m_BTAsyncExControl) then
  161. if failed(m_BTAsyncExControl.SetBuffersize(TrackBar2.Position * 1000)) then
  162. exit;
  163. if assigned(m_BTAsycEx) then
  164. if failed(m_BTAsycEx.FindPin(PinID, m_Pin)) then
  165. exit;
  166. if assigned(m_GraphBuilder) then
  167. if failed(m_GraphBuilder.AddFilter(m_BTAsycEx,
  168. StringToOleStr(FilterID))) then
  169. exit;
  170. if assigned(m_Mp3Dec) then
  171. if failed(m_GraphBuilder.AddFilter(m_Mp3Dec,
  172. StringToOleStr('MP3 Dec'))) then
  173. exit;
  174. if assigned(m_GraphBuilder) then
  175. if failed(m_GraphBuilder.Render(m_Pin)) then
  176. exit;
  177. if assigned(m_MediaControl) then
  178. if failed(m_MediaControl.Run) then
  179. exit;
  180. end;
  181. procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
  182. begin
  183. NilAll;
  184. TmrCloseApp.Enabled := true;
  185. { CoUninitialize causes a crash when closing the
  186. Application while preBuffering }
  187. // CoUninitialize;
  188. end;
  189. procedure TForm1.FormCreate(Sender: TObject);
  190. begin
  191. ListBox1.ItemIndex := 0;
  192. PageControl1.DoubleBuffered := true;
  193. { CoUninitialize causes a crash when closing the
  194. Application while preBuffering, however works also without CoInitialize }
  195. // CoInitialize(nil);
  196. m_ripdir := GetCurrentDir;
  197. if length(m_ripdir) > 50 then
  198. label11.Caption := copy(m_ripdir, 1, 50) + '...'
  199. else
  200. label11.Caption := m_ripdir;
  201. label11.Hint := m_ripdir;
  202. label11.ShowHint := true;
  203. label18.Hint := label18.Caption;
  204. label18.ShowHint := true;
  205. label19.Hint := label19.Caption;
  206. label19.ShowHint := true;
  207. label19.Font.Color := clBlue;
  208. label19.Font.Style := [fsUnderline];
  209. label24.Hint := label24.Caption;
  210. label24.ShowHint := true;
  211. label25.Hint := label25.Caption;
  212. label25.ShowHint := true;
  213. label26.Hint := label26.Caption;
  214. label26.ShowHint := true;
  215. label26.Font.Color := clBlue;
  216. label26.Font.Style := [fsUnderline];
  217. Label8.Caption := inttostr(TrackBar1.Position) + ' kb';
  218. Label3.Caption := inttostr(TrackBar2.Position) + ' kb';
  219. end;
  220. procedure TForm1.TrackBar1Change(Sender: TObject);
  221. begin
  222. Label8.Caption := inttostr(TrackBar1.Position) + ' kb';
  223. end;
  224. procedure TForm1.Button6Click(Sender: TObject);
  225. begin
  226. if Button6.Caption = 'connect' then
  227. OpenURL
  228. else begin
  229. Button6.Enabled := false;
  230. nilall;
  231. Button6.Enabled := true;
  232. end;
  233. end;
  234. function TForm1.AsyncExFilterState(Buffering: LongBool; PreBuffering: LongBool;
  235. Connecting: LongBool; Playing: LongBool;
  236. BufferState: integer): HRESULT; stdcall;
  237. begin
  238. if PreBuffering then
  239. Label6.Caption := '( ' + inttostr(BufferState) + '% )' + ' prebuffering....';
  240. if Buffering then begin
  241. Label6.Caption := '( ' + inttostr(BufferState) + '% )' + ' buffering....';
  242. end;
  243. if Connecting then
  244. Label6.Caption := 'connecting....';
  245. if Playing then begin
  246. Label6.Caption := 'playing....';
  247. end;
  248. if not Buffering and not PreBuffering and not Connecting and not Playing then begin
  249. Label6.Caption := 'N/A';
  250. Label18.Caption := 'N/A';
  251. Label19.Caption := 'N/A';
  252. end;
  253. Result := S_OK;
  254. end;
  255. function TForm1.AsyncExICYNotice(IcyItemName: PChar;
  256. ICYItem: PChar): HRESULT; stdcall;
  257. const // ICY Item Names
  258. c_ICYMetaInt = 'icy-metaint:';
  259. c_ICYName = 'icy-name:';
  260. c_ICYGenre = 'icy-genre:';
  261. c_ICYURL = 'icy-url:';
  262. c_ICYBitrate = 'icy-br:';
  263. c_ICYError = 'icy-error:';
  264. begin
  265. if IcyItemName = c_ICYError then begin
  266. ListBox1.Enabled := false;
  267. Button6.Enabled := false;
  268. showmessage(copy(ICYItem, 1, length(ICYItem)));
  269. TmrNilAll.Enabled := true;
  270. end;
  271. if IcyItemName = c_ICYName then begin
  272. if length(ICYItem) > 39 then
  273. label24.Caption := copy(ICYItem, 1, 75) + '...'
  274. else
  275. label24.Caption := copy(ICYItem, 1, length(ICYItem));
  276. label24.Hint := copy(ICYItem, 1, length(ICYItem));
  277. end;
  278. if IcyItemName = c_ICYGenre then begin
  279. if length(ICYItem) > 39 then
  280. label25.Caption := copy(ICYItem, 1, 75) + '...'
  281. else
  282. label25.Caption := copy(ICYItem, 1, length(ICYItem)); ;
  283. label25.Hint := copy(ICYItem, 1, length(ICYItem));
  284. end;
  285. if IcyItemName = c_ICYURL then begin
  286. if length(ICYItem) > 30 then
  287. label26.Caption := copy(ICYItem, 1, 75) + '...'
  288. else
  289. label26.Caption := copy(ICYItem, 1, length(ICYItem));
  290. label26.Hint := copy(ICYItem, 1, length(ICYItem));
  291. end;
  292. if IcyItemName = c_ICYBitrate then
  293. label27.Caption := copy(ICYItem, 1, length(ICYItem));
  294. Result := S_OK;
  295. end;
  296. function TForm1.AsyncExSockError(ErrString: PChar): HRESULT; stdcall;
  297. begin
  298. ListBox1.Enabled := false;
  299. Button6.Enabled := false;
  300. showmessage('can not connect to URL'#13#10#13#10 +
  301. 'Reason:'#13#10 + copy(ErrString, 1, length(ErrString)));
  302. //NilAll;
  303. TmrNilAll.Enabled := true;
  304. Result := S_OK;
  305. end;
  306. function TForm1.AsyncExMetaData(Title: PChar; URL: PChar): HRESULT; stdcall;
  307. begin
  308. if length(Title) > 50 then
  309. Label18.Caption := copy(Title, 1, 45) + '...'
  310. else
  311. Label18.Caption := copy(Title, 1, length(Title));
  312. Label18.Hint := copy(Title, 1, length(Title));
  313. if length(URL) > 50 then
  314. Label19.Caption := copy(URL, 1, 45) + '...'
  315. else
  316. Label19.Caption := copy(URL, 1, length(URL));
  317. Label19.Hint := copy(URL, 1, length(URL));
  318. Result := S_OK;
  319. end;
  320. procedure TForm1.refreshripstream();
  321. begin
  322. if CheckBox1.Checked then begin
  323. if assigned(m_BTAsyncExControl) then
  324. m_BTAsyncExControl.SetRipStream(true, PChar(m_ripdir), PChar(Edit4.Text));
  325. end else begin
  326. if assigned(m_BTAsyncExControl) then
  327. m_BTAsyncExControl.SetRipStream(false, PChar(m_ripdir), PChar(Edit4.Text));
  328. end;
  329. end;
  330. procedure TForm1.CheckBox1Click(Sender: TObject);
  331. begin
  332. refreshripstream();
  333. end;
  334. procedure TForm1.TrackBar2Change(Sender: TObject);
  335. begin
  336. Label3.Caption := inttostr(TrackBar2.Position) + ' kb';
  337. if assigned(m_BTAsyncExControl) then
  338. m_BTAsyncExControl.SetBuffersize(TrackBar2.Position * 1000);
  339. end;
  340. procedure TForm1.ListBox1DblClick(Sender: TObject);
  341. begin
  342. nilall;
  343. TmrOpenUrl.Enabled := true;
  344. end;
  345. procedure TForm1.TmrNilAllTimer(Sender: TObject);
  346. begin
  347. TmrNilAll.Enabled := false;
  348. nilall;
  349. ListBox1.Enabled := true;
  350. Button6.Enabled := true;
  351. end;
  352. procedure TForm1.TmrOpenUrlTimer(Sender: TObject);
  353. begin
  354. TmrOpenUrl.Enabled := false;
  355. OpenURL;
  356. end;
  357. procedure TForm1.TmrCloseAppTimer(Sender: TObject);
  358. begin
  359. Close;
  360. end;
  361. end.