⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 u_icy_client.pas

📁 Voice Commnucation Components for Delphi
💻 PAS
📖 第 1 页 / 共 2 页
字号:
      if (c_checkBox_autoPush.checked) then begin
	//
	dec(f_aiutoPushCountdown);
	if (1 > f_aiutoPushCountdown) then begin
	  //
	  f_aiutoPushCountdown := 20;	// wait 20 * a_timer_main.interval ms before next push
	  c_edit_songTitle.text := 'Live, local time: ' + timeToStr(now);
	  a_str_push.execute();
	end
      end;
    end;

    else

  end;

  //
  case (f_consumer.status) of

    iss_disconnected: begin
      //
      if (not a_lst_start.enabled and a_lst_stop.enabled) then
	a_lst_stop.execute();
    end;

    iss_connected: begin
      //
      subStrLst := ', received/buffered ' + int2str(f_dataInSize shr 10, 10, 3) + '/' + int2str(f_waveOut.getDataAvailable(true) shr 10, 10, 3) + ' KBytes.';
      //
      kbps := f_consumer.getServerHeaderValue('icy-br');
      genre := f_consumer.getServerHeaderValue('icy-genre');
      name := f_consumer.getServerHeaderValue('icy-name');
      url := f_consumer.getServerHeaderValue('icy-url');
      //
      if ('' = kbps) then
	// try Ice 1.3 header
	kbps := f_consumer.getServerHeaderValue('x-audiocast-bitrate');
      //
      if ('' = genre) then
	// try Ice 1.3 header
	genre := f_consumer.getServerHeaderValue('x-audiocast-genre');
      //
      if ('' = name) then
	// try Ice 1.3 header
	name := f_consumer.getServerHeaderValue('x-audiocast-description');
      //
      if ('' = url) then
	// try Ice 1.3 header
	url := f_consumer.getServerHeaderValue('x-audiocast-server-url');
      //
      streamInfo := 'Format     : ' + kbps + ' kbps; ' + f_waveOut.srcFormatInfo + #13#10 +
		    'Name       : ' + name + ' (' + genre + ')' + #13#10 +
		    'URL        : ' + url + #13#10 +
		    'Song Title : ' + f_consumer.songTitle + #13#10 +
		    'Song URL   : ' + f_consumer.songUrl + #13#10;
      //
      c_memo_streamInfo.text := streamInfo;
    end;

    else
      ;

  end;
  //
  c_label_strStatus.caption := 'Status: ' + iss2str(f_provider.status) + subStrStr;
  c_label_lstStatus.caption := 'Status: ' + iss2str(f_consumer.status) + subStrLst;
end;

// --  --
procedure Tc_form_main.urlLabelClick(Sender: TObject);
begin
  if (sender is tLabel) then
    shellExecute(0, 'open', pChar((sender as tLabel).hint), nil, nil, SW_SHOWNORMAL);
end;

// --  --
procedure Tc_form_main.c_checkBox_autoPushClick(Sender: TObject);
begin
  c_edit_songTitle.enabled := not c_checkBox_autoPush.checked;
  if (c_checkBox_autoPush.checked) then
    f_aiutoPushCountdown := 1;	// push now
end;

// --  --
procedure Tc_form_main.a_str_configExecute(Sender: TObject);
begin
  if (mrOK = c_form_streamerConfig.showModal()) then
    updateStrConfigInfo();
end;

// --  --
procedure Tc_form_main.a_lst_configExecute(Sender: TObject);
begin
  if (mrOK = c_form_lstConfig.showModal()) then
    updateLstConfigInfo();
end;

// --  --
procedure Tc_form_main.updateStrConfigInfo();
begin
  f_provider.title := strTitle;
  f_provider.URL := strURL;
  f_provider.genre := strGenre;
  f_provider.bitrate := strBitrate;
  f_provider.allowPublishing := strAllowPublishing;
  //
  c_label_strInfo.caption := strTitle + ' (' + strGenre + ') at ' + int2str(strBitrate) + ' kbps, ' + choice(strStereo, 'stereo', 'mono') + '.';
  //
  freeAndNil(f_lame);
  f_lame := unaLameMp3Enc.create(strEncoder, THREAD_PRIORITY_TIME_CRITICAL);
  f_lameError := f_lame.errorCode;
  //
  if (BE_ERR_SUCCESSFUL = f_lameError) then begin
    //
    c_label_encoderInfo.caption := 'Lame encoder, version ' + int2str(f_lame.version.byMajorVersion) + '.' + int2str(f_lame.version.byMinorVersion);
    f_lame.onDataAvailable := encoderDataAvail;
  end
  else begin
    //
    c_label_encoderInfo.caption := 'Lame encoder was not found.';
    //
    f_lameError := -1;
    freeAndNil(f_lame);
  end;
end;

// --  --
procedure Tc_form_main.updateLstConfigInfo();
begin
  freeAndNil(f_bassStreamThread);
  freeAndNil(f_bassStream);
  freeAndNil(f_bass);
  //
  freeAndNil(f_mpgDecoder);
  //
  if (0 < pos('bass', lowerCase(lstDecoder))) then begin
    //
    f_bass := unaBass.create(lstDecoder, {$IFDEF BASS_AFTER_18 }0{$ELSE }-1{$ENDIF }, 44100, 32, handle);
    //
    f_bassError := f_bass.get_errorCode();
    if (BASS_OK = f_bassError) then begin
      //
      f_bassStream := unaBassStream.create(f_bass);
      f_bassStreamThread := localBassStreamDecoder.create();
      //
      c_label_decoderInfo.caption := 'BASS decoder, version ' + f_bass.get_versionStr();
    end
    else begin
      //
      c_label_decoderInfo.caption := 'Not a BASS decoder module.';
      //
      f_bassError := -1;
      freeAndNil(f_bass);
    end;
  end;

  if (nil = f_bass) then begin
    //
    // try mpgLib instead
    //
    f_mpgDecoder := localMpgLibDecoder.create(lstDecoder);
    if (mpglib_error_OK = f_mpgDecoder.errorCode) then
      //
      c_label_decoderInfo.caption := 'MpgLib decoder, version 0'
    else begin
      c_label_decoderInfo.caption := 'Unknown decoder module';
      //
      freeAndNil(f_mpgDecoder);
    end;
  end;
  //
  c_label_lstInfo.caption := 'Live playback';
end;

// --  --
procedure Tc_form_main.configLame(bitRate, samplingRate: unsigned; stereo: bool);
var
  lameConfig: BE_CONFIG_FORMATLAME;
begin
  f_lameError := -1;
  if (nil <> f_lame) then begin
    //
    fillChar(lameConfig, sizeOf(lameConfig), #0);
    lameConfig.dwConfig := BE_CONFIG_LAME;
    //
    with lameConfig.r_lhv1 do begin
      //
      dwStructVersion := CURRENT_STRUCT_VERSION;
      dwStructSize := sizeOf(lameConfig);
      dwSampleRate := samplingRate;
      dwReSampleRate := dwSampleRate;
      //
      if (stereo) then
	nMode := BE_MP3_MODE_STEREO
      else
	nMode := BE_MP3_MODE_MONO;
      //
      dwBitrate := bitRate;
      dwMaxBitrate := bitRate;
      //
      nPreset := LQP_NOPRESET;
      dwMpegVersion := MPEG2;
      //
      bPrivate := true;
      bCRC := false;
      bCopyright := true;
      bOriginal := true;
      //
      bWriteVBRHeader := false;
      bEnableVBR := false;
      nVbrMethod := VBR_METHOD_NONE;
      //
      bNoRes := true;
      bStrictIso := false;
    end;
    //
    f_lameError := f_lame.setConfig(@lameConfig);
    if (BE_ERR_SUCCESSFUL = f_lameError) then
      f_lameError := f_lame.open();
    //
    if (BE_ERR_SUCCESSFUL <> f_lameError) then
      c_label_encoderInfo.caption := 'Lame error: ' + int2str(f_lameError);
  end;
end;

// --  --
procedure Tc_form_main.encoderDataAvail(sender: tObject; data: pointer; size: unsigned; var copyToStream: bool);
begin
  if (iss_connected = f_provider.status) then
    inc(f_dataOutSize, f_provider.sendData(data, size));
  //
  // no need to save the data locally
  copyToStream := false;
end;

// --  --
procedure Tc_form_main.a_str_startExecute(Sender: TObject);
var
  samplingRate: int;
  err: int;
begin
  a_str_start.enabled := false;
  a_str_config.enabled := false;
  //
  try
    f_dataOutSize := 0;
    //
    case (strBitrate) of

      000..016: samplingRate := 8000;
      017..032: samplingRate := 11025;
      033..064: samplingRate := 22050;
      065..096: samplingRate := 32000;

      else      samplingRate := 44100;

    end;
    //
    configLame(strBitrate, samplingRate, strStereo);
    if (BE_ERR_SUCCESSFUL = f_lameError) then begin
      //
      //f_waveIn.deviceId := deviceId;
      //
      f_waveIn.setSampling(samplingRate, 16, choice(strStereo, 2, unsigned(1)));
      err := f_waveIn.open();
      //
      if (f_waveIn.isOpen) then begin
	// start provider
	f_provider.password := c_edit_password.text;
	f_provider.host := c_edit_host.text;
	f_provider.port := c_edit_port.text;
	//
	f_provider.start();
      end
      else begin
	//
	raise exception.create('Unable to open recording device, error text: '#13#10 + f_waveIn.getErrorText(err));
      end;
      //
      a_str_stop.enabled := true;
      a_str_push.enabled := true;
    end
    else
      raise exception.create('Unable to configure encoder, error code: ' + int2str(f_lameError));
    //
  except
    a_str_start.enabled := true;
    a_str_config.enabled := true;
    //
    raise;
  end;
end;

// --  --
procedure Tc_form_main.a_str_stopExecute(Sender: TObject);
begin
  a_str_stop.enabled := false;
  //
  try
    f_waveIn.close();
    f_lame.close();
    f_provider.stop();
  except
  end;
  //
  a_str_start.enabled := true;
  a_str_push.enabled := false;
  a_str_config.enabled := true;
end;

// --  --
procedure Tc_form_main.a_str_pushExecute(Sender: TObject);
begin
  f_provider.pushSongTitle(c_edit_songTitle.text, c_edit_songURL.text);
end;

// --  --
procedure Tc_form_main.waveDataAvail(sender: tObject; data: pointer; size: unsigned);
begin
  if ((nil <> f_lame) and (BE_ERR_SUCCESSFUL = f_lameError)) then
    // use lazy thread to return to waveIn ASAP
    f_lame.lazyWrite(data, size);
end;

// --  --
procedure Tc_form_main.a_lst_startExecute(Sender: TObject);
begin
  a_lst_start.enabled := false;
  a_lst_config.enabled := false;
  //
  try
    if (((nil <> f_bass) and (BASS_OK = f_bassError)) or (nil <> f_mpgDecoder)) then begin
      // start consumer
      f_dataInSize := 0;
      f_dataStream.clear();
      //
      f_consumer.host := c_edit_host.text;
      f_consumer.port := c_edit_port.text;
      f_consumer.URL := c_edit_listenerURL.text;
      //
      f_consumer.start();
      //
      a_lst_stop.enabled := true;
      //
      if (nil <> f_mpgDecoder) then
	f_mpgDecoder.start();
    end
    else
      raise exception.create('Decoder was not found.');
    //  
  except
    a_lst_start.enabled := true;
    a_lst_config.enabled := true;
    //
    raise;
  end;
end;

// --  --
procedure Tc_form_main.a_lst_stopExecute(sender: tObject);
begin
  a_lst_stop.enabled := false;
  //
  try
    f_consumer.stop();
    f_dataStream.clear();
    //
    if (nil <> f_bass) then
      f_bassStreamThread.stop();
    //
    if (nil <> f_mpgDecoder) then
      f_mpgDecoder.stop();
    //
    f_waveOut.flush(false);
    f_waveOut.close();
  except
  end;
  //
  a_lst_start.enabled := true;
  a_lst_config.enabled := true;
end;

// --  --
procedure Tc_form_main.consumerDataAvail(sender: tObject; data: pointer; size: unsigned);
begin
  inc(f_dataInSize, size);
  //
  if (nil <> f_bass) then begin
    //
    f_dataStream.write(data, size);
    f_bassStreamThread.start();
  end;
  //
  if (nil <> f_mpgDecoder) then
    f_mpgDecoder.write(data, size);
end;


end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -