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

📄 advoip.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    end;
  end;
end;

function TApdCustomVoIP.InitializeTapi: HRESULT;
  { get the interface to TAPI3 }
begin
  Result := CoCreateInstance(CLASS_TAPI, nil, CLSCTX_INPROC_SERVER,
    IID_ITTAPI, gpTapi);
  if Result <> S_OK then begin                                           {!!.01}
    FErrorCode := ecVoIPTapi3NotInstalled;                               {!!.01}
    DoFailEvent;                                                         {!!.01}
    Exit;
  end;                                                                   {!!.01}

  gpTapi.Initialize;

  { create the event notification object and register it }
  Result := RegisterTapiEventInterface;
  if Result <> S_OK then begin
    FErrorCode := ecVoIPTapi3EventFailure;                               {!!.01}
    DoFailEvent;                                                         {!!.01}       
    Exit;
  end;

  Result := FindTheAddress;

  if Result <> S_OK then begin
    { no address (H.323 line) found }
    FErrorCode := ecVoIPBadAddress;                                      {!!.01}
    DoFailEvent;                                                         {!!.01}
    gpTapi := nil;
  end;
end;

function TApdCustomVoIP.IsAudioCaptureStream(pStream: ITStream): Boolean;
  { see if this stream is the audio capture stream }
begin
  Result := (pStream.Get_Direction in [TD_CAPTURE, TD_BIDIRECTIONAL]) and
            (pStream.Get_MediaType = TAPIMEDIATYPE_AUDIO);
end;

function TApdCustomVoIP.IsAudioRenderStream(pStream: ITStream): Boolean;
  { see if this stream is the audio render stream }
begin
  Result := (pStream.Get_Direction in [TD_RENDER, TD_BIDIRECTIONAL]) and
            (pStream.Get_MediaType = TAPIMEDIATYPE_AUDIO);
end;

function TApdCustomVoIP.IsVideoCaptureStream(pStream: ITStream): Boolean;
  { see if this stream is the video capture stream }
begin
  Result := (pStream.Get_Direction in [TD_CAPTURE, TD_BIDIRECTIONAL]) and
            (pStream.Get_MediaType = TAPIMEDIATYPE_VIDEO);
end;

function TApdCustomVoIP.IsVideoRenderStream(pStream: ITStream): Boolean;
  { see if this stream is the video render stream }
begin
  Result := (pStream.Get_Direction in [TD_RENDER, TD_BIDIRECTIONAL]) and
            (pStream.Get_MediaType = TAPIMEDIATYPE_VIDEO);
end;

procedure TApdCustomVoIP.Loaded;
var
  Res : HRESULT;
begin
  inherited;
  FVoIPAvailable := False;
  { determine whether TAPI 3 is installed }
  Res := CoCreateInstance(CLASS_TAPI, nil, CLSCTX_INPROC_SERVER,
    IID_ITTAPI, gpTapi);
  if Res <> S_OK then begin                                              {!!.01}
    FErrorCode := ecVoIPTapi3NotInstalled;                               {!!.01}
    DoFailEvent;                                                         {!!.01}
    Exit;
  end;                                                                   {!!.01}
  try
    gpTapi.Initialize;

    { determine whether the H323 address is available }
    Res := FindTheAddress;
    if Res <> S_OK then begin
      {FVoIPAvailable := False;}                                         {!!.01}
      FErrorCode := ecVoIPH323NotFound;                                  {!!.01}
      DoFailEvent;                                                       {!!.01}
      gpTapi := nil;
      Exit;
    end;
    { figure out which terminals are available to us }
    LoadTerminals;
    FVoIPAvailable := True;
  finally
    { unregister our call notification }
    if NotifyRegister > 0 then
      gpTapi.UnregisterNotifications(NotifyRegister);
    NotifyRegister := 0;
    gpAddress := nil;
    gpCall := nil;
    gpTapi := nil;
    gpTAPIEventNotification := nil;
  end;
end;

procedure TApdCustomVoIP.LoadTerminals;
{- Enumerates available terminals (audio/video hardware devices) }
{  adding each to AvailableTerminalDevices collection            }
var
  pTerminal : ITTerminal;
  pTerminalSupport : ITTerminalSupport;
  RecordsFound : DWORD;
  Term : TApdVoIPTerminal;
  pTermEnum : IEnumTerminal;
  WS : WideString;
begin
  { clear the collection }
  FAvailableTerminalDevices.Clear;
  { get the terminal support interface from our address }
  pTerminalSupport := (gpAddress as ITTerminalSupport);
  { enumerate the terminals }
  pTermEnum := pTerminalSupport.EnumerateStaticTerminals;
  if pTermEnum <> nil then
    while pTermEnum.Next(1, pTerminal, RecordsFound) = S_OK do begin
      { found a terminal, extract the terminal properties }
      Term := (FAvailableTerminalDevices.Add as TApdVoIPTerminal);
      Term.FDeviceName := pTerminal.Name;
      case pTerminal.Get_MediaType of
         TAPIMEDIATYPE_AUDIO     : Term.FMediaType := mtAudio;
         TAPIMEDIATYPE_VIDEO     : Term.FMediaType := mtVideo;
         TAPIMEDIATYPE_DATAMODEM : Term.FMediaType := mtDataModem;
         TAPIMEDIATYPE_G3FAX     : Term.FMediaType := mtG3_Fax;
      end;
      case pTerminal.Get_Direction of
        TD_CAPTURE       : Term.FMediaDirection := mdCapture;
        TD_RENDER        : Term.FMediaDirection := mdRender;
        TD_BIDIRECTIONAL : Term.FMediaDirection := mdBidirectional;
      end;
      WS := pTerminal.Get_TerminalClass;
      if WS = CLSID_String_HandsetTerminal then
        Term.FTerminalDeviceClass := dcHandsetTerminal
      else if WS = CLSID_String_HeadsetTerminal then
        Term.FTerminalDeviceClass := dcHeadsetTerminal
      else if WS = CLSID_String_MediaStreamTerminal then
        Term.FTerminalDeviceClass := dcMediaStreamTerminal
      else if WS = CLSID_String_MicrophoneTerminal then
        Term.FTerminalDeviceClass := dcMicrophoneTerminal
      else if WS = CLSID_String_SpeakerphoneTerminal then
        Term.FTerminalDeviceClass := dcSpeakerPhoneTerminal
      else if WS = CLSID_String_SpeakersTerminal then
        Term.FTerminalDeviceClass := dcSpeakersTerminal
      else if WS = CLSID_String_VideoInputTerminal then
        Term.FTerminalDeviceClass := dcVideoInputTerminal
      else if WS = CLSID_String_VideoWindowTerm then
        Term.FTerminalDeviceClass := dcVideoWindowTerminal;

      case pTerminal.Get_TerminalType of
        TT_STATIC  : Term.FTerminalType := ttStatic;
        TT_DYNAMIC : Term.FTerminalType := ttDynamic;
      end;

      case pTerminal.Get_State of
        TS_INUSE    : Term.FTerminalState := tsInUse;
        TS_NOTINUSE : Term.FTerminalState := tsNotInUse;
      end;
    end;
end;

function TApdCustomVoIP.MakeTheCall(dwAddressType: DWORD;
  szAddressToCall: WideString): Boolean;
var
  lMediaTypes : TOleEnum;
  pCallInfo : ITCallInfo;
begin
  Result := False;
  lMediaTypes := 0;
  if (AddressSupportsMediaType (gpAddress, TAPIMEDIATYPE_AUDIO)) then
    lMediaTypes := TAPIMEDIATYPE_AUDIO;
  { only enable the video media mode if we want video }
  if (AddressSupportsMediaType (gpAddress, TAPIMEDIATYPE_VIDEO)) then
    lMediaTypes := lMediaTypes or TAPIMEDIATYPE_VIDEO;

  gpCall := gpAddress.CreateCall(szAddressToCall, dwAddressType, lMediaTypes);

  if not Assigned(gpCall) then
    Exit;

  if gpCall.QueryInterface(IID_ITCallInfo, pCallInfo) = S_OK then begin
    { these are the only parts of the pCallInfo that can be set }
    if Length(FCallComment) > 0 then                                     {!!.01}
      pCallInfo.Set_CallInfoString(CIS_COMMENT, FCallComment);
    if Length(FCallDisplayableAddress) > 0 then                          {!!.01}
      pCallInfo.Set_CallInfoString(CIS_DISPLAYABLEADDRESS,
        FCallDisplayableAddress);
    { PhoneDialer uses CallingPartyID for it's display }
    if Length(FCallCallingPartyID) > 0 then                              {!!.01}
      pCallInfo.Set_CallInfoString(CIS_CALLINGPARTYID, FCallCallingPartyID);
  end;

  if SelectTerminalOnCall(gpAddress, gpCall) <> S_OK then begin
    { couldn't select a terminal, just go without it }
  end;

  try
    { start the connection timer, FConnectTimeout is measured in seconds }
    if FConnectTimeout > 0 then                                          {!!.04}
      SetTimer(FHandle, FConnectTimer, (FConnectTimeout * 1000), nil);   {!!.04}
    gpCall.Connect(False);
    Result := True;
  except
    { call failed, the exception will be raised here (and trapped here) }
    { the OnFail event will be generated with the reason for the error  }
    { from the event sink }
  end;

end;

procedure TApdCustomVoIP.Notification(AComponent : TComponent; Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) then begin
    if (AComponent = FVideoOutWindow) then
      FVideoOutWindow := nil;
    if (AComponent = FPreviewWindow) then
      FPreviewWindow := nil;
  end;
end;

procedure TApdCustomVoIP.ProcessTapiEvent(TapiEvent: TAPI_EVENT;
  pEvent: IDispatch);
  { called as a result of receiving apw_VoIPEventMessage message from the sink }
var
  hr : HRESULT;
  pNotify : ITCallNotificationEvent;
  pCallInfo : ITCallInfo;
  pCallStateEvent : ITCallStateEvent;
  pCallMediaEvent : ITCallMediaEvent;
  pTerminal : ITTerminal;
  fRenderStream : Boolean;
  pVideoWindow : IVideoWindow;
begin
  case TapiEvent of
    TE_CALLNOTIFICATION : { we're being notified of a new call }
      begin
        hr := pEvent.QueryInterface(IID_ITCallNotificationEvent, pNotify);
        if hr <> S_OK then begin
          { DoMessage('Incoming call, but failed to get the interface'); }
        end else begin
          pCallInfo := pNotify.Get_Call;
          pNotify._Release;
          if pCallInfo <> nil then begin
            try
              FCallerIDName := pCallInfo.Get_CallInfoString(CIS_CALLERIDNAME);
            except
              FCallerIDName := 'Not available';
            end;
            try
              FCallerIDNumber := pCallInfo.Get_CallInfoString(CIS_CALLERIDNUMBER);
            except
              FCallerIDNumber := 'Not available';
            end;
            try
              FCallerDisplayName := pCallInfo.Get_CallInfoString(CIS_DISPLAYABLEADDRESS);
            except
              FCallerDisplayName := 'Not available';
            end;
            if pCallInfo.get_Privilege <> CP_OWNER then begin
              { not our call, just exit }
              Exit;
            end;
            { get the ITBasicCallControl interface }
            hr := pCallInfo.QueryInterface(IID_ITBasicCallControl, gpCall);
            if hr = S_OK then begin
              PostMessage(FHandle, apw_VoIPEventMessage, etIncomingCall, 0);
            end;
          end;
        end;
      end;
    TE_CALLSTATE : { call state event }
      begin
        hr := pEvent.QueryInterface(IID_ITCallStateEvent, pCallStateEvent);
        if hr = S_OK then begin
          { get the CallState event }
          case pCallStateEvent.get_State of
            CS_IDLE,
            CS_INPROGRESS :
              begin
                PostMessage(FHandle, apw_VoIPEventMessage, etCallState,
                  pCallStateEvent.get_State);
              end;
            CS_OFFERING :
              begin
                if FWaitingForCall then
                  PostMessage(FHandle, apw_VoIPEventMessage, etAnswer, 0);
              end;
            CS_DISCONNECTED :
              begin
                PostMessage(FHandle, apw_VoIPEventMessage, etDisconnected,
                  pCallStateEvent.Get_Cause);                            {!!.01}
              end;
            CS_CONNECTED :
              begin
                PostMessage(FHandle, apw_VoIPEventMessage, etConnect, 0);
              end;
          end;
          { get the CallState event cause }
          case pCallStateEvent.Get_Cause of
            CEC_NONE,
            CEC_DISCONNECT_NORMAL :
              begin
                { nothing to do, normal disconnect }
              end;
            CEC_DISCONNECT_BUSY,
            CEC_DISCONNECT_BADADDRESS,
            CEC_DISCONNECT_NOANSWER,
            CEC_DISCONNECT_CANCELLED,
            CEC_DISCONNECT_REJECTED,
            CEC_DISCONNECT_FAILED :
              begin
                PostMessage(FHandle, apw_VoIPEventMessage, etFail,
                  pCallStateEvent.Get_Cause);
              end;
          end;
        end;
      end;
    TE_CALLMEDIA :
      begin
        hr := pEvent.QueryInterface(IID_ITCallMediaEvent, pCallMediaEvent);
        if hr = S_OK then begin
          case pCallMediaEvent.get_Event of
            CME_STREAM_NOT_USED,
            CME_NEW_STREAM : { nothing to do } ;
            CME_STREAM_FAIL :
              begin
                { DoMessage('Call media event: stream failed'); }
              end;

⌨️ 快捷键说明

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