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

📄 advoip.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
            CME_STREAM_INACTIVE :
              begin
                { refresh our terminal collection }
                LoadTerminals;
              end;
            CME_TERMINAL_FAIL :
              begin
                { DoMessage('Call media event: terminal failed'); }
              end;
            CME_STREAM_ACTIVE :
              begin
                { see if this is a video render terminal }
                hr := GetVideoRenderTerminalFromStream(pCallMediaEvent,
                  pTerminal, fRenderStream);
                if hr = S_OK then begin
                  pVideoWindow := nil;
                  hr := pTerminal.QueryInterface(IID_IVideoWindow,
                    pVideoWindow);
                  if hr = S_OK then begin
                    HostWindow(pVideoWindow, fRenderStream);
                  end;
                end;
                { refresh our terminal collection }
                LoadTerminals;
              end;
          end;
        end;
      end;
  end;
end;

function TApdCustomVoIP.RegisterTapiEventInterface: HRESULT;
  { create the event sink and register it }
var
  pCPC : IConnectionPointContainer;
  pCP : IConnectionPoint;
begin
  {Create  event sink}
  gpTAPIEventNotification := TApdTapiEventSink.Create(self);

  {ensure valid}
  if gpTAPIEventNotification = nil then begin
    Result := E_FAIL;
    Exit;
  end;

  Result := gpTapi.QueryInterface(IID_IConnectionPointContainer, pCPC);
  if Result <> S_OK then Exit;

  Result := pCPC.FindConnectionPoint(IID_ITTAPIEventNotification, pCP);
  if Result <> S_OK then Exit;

  Result := pCP.Advise(gpTAPIEventNotification, gulAdvise);

  { set the event filter to only give us the events we want }
  gpTapi.Set_EventFilter(TE_CALLNOTIFICATION or TE_CALLSTATE or TE_CALLMEDIA);
end;

procedure TApdCustomVoIP.ReleaseTheCall;
  { um, release the call }
begin
  if gpCall <> nil then
    gpCall := nil;
end;

function TApdCustomVoIP.SelectTerminalOnCall(pAddress: ITAddress;
  pCall: ITBasicCallControl): HRESULT;
  { find and select the terminals for the call }
var
  pStreamControl : ITStreamControl;
  pEnumStreams : IEnumStream;
  pStream : ITStream;
  pTerminal : ITTerminal;
  Fetched : DWORD;
begin
  { get the ITStreamControl interface for this call }
  Result := pCall.QueryInterface(IID_ITStreamControl, pStreamControl);
  if Result = S_OK then begin
    { enumerate the streams }
    pStreamControl.EnumerateStreams(pEnumStreams);
    if pEnumStreams = nil then begin
      Result := E_OUTOFMEMORY;
      Exit;
    end;
    while pEnumStreams.Next(1, pStream, Fetched) = S_OK do begin
      { find the media type and direction of this stream and create }
      { the default terminal for this media type and direction      }
      Result := GetTerminal(pAddress, pStream, pTerminal);
      if Result = S_OK then begin
        { select the terminal on the stream }
        pStream.SelectTerminal(pTerminal);
        if IsVideoCaptureStream(pStream) and FEnablePreview then
          EnablePreviewWindow(pAddress, pStream);
      end;
    end;
  end;
end;

procedure TApdCustomVoIP.SetAudioInDevice(const Value: string);
  { AudioOutDevice write access method }
begin
  FAudioInDevice := Value;
  if UpperCase(FAudioInDevice) = UpperCase(ApdDefaultTerminalName) then
    FAudioInDevice := ApdDefaultTerminalName;
  if (UpperCase(FAudioInDevice) = UpperCase(ApdNoTerminalName)) or
    (FAudioInDevice = '') then
    FAudioInDevice := ApdNoTerminalName;
end;

procedure TApdCustomVoIP.SetAudioOutDevice(const Value: string);
  { AudioOutDevice write access method }
begin
  FAudioOutDevice := Value;
  if UpperCase(FAudioOutDevice) = UpperCase(ApdDefaultTerminalName) then
    FAudioOutDevice := ApdDefaultTerminalName;
  if (UpperCase(FAudioOutDevice) = UpperCase(ApdNoTerminalName)) or
     (FAudioOutDevice = '')  then
    FAudioOutDevice := ApdNoTerminalName;
end;

procedure TApdCustomVoIP.SetEnablePreview(const Value: Boolean);
  { EnablePreview write access method }
begin
  FEnablePreview := Value;
  if not FEnableVideo then
    { Preview is only available if we're transmitting video }
    FEnablePreview := False;
end;

procedure TApdCustomVoIP.SetEnableVideo(const Value: Boolean);
  { EnableVideo write access method }
begin
  FEnableVideo := Value;
  if not FEnableVideo then
    { Preview is only available if we're transmitting video }
    FEnablePreview := False;
end;

procedure TApdCustomVoIP.SetPreviewWindow(const Value: TWinControl);
  { PreviewWindow write access method }
begin
  FPreviewWindow := Value;
end;

procedure TApdCustomVoIP.SetPreviewWindowAutoSize(const Value: Boolean);
begin
  { NOTE: Setting this property while stream is being rendered not supported }
  FPreviewWindowAutoSize := Value;
end;

procedure TApdCustomVoIP.SetVideoInDevice(const Value: string);
  { VideoInDevice write access method }
begin
  { only default video in (local camera) terminal supported }
  { property is limited to '<none>' or '<default>'          }
  FVideoInDevice := Value;
  if (UpperCase(FVideoInDevice) = UpperCase(ApdNoTerminalName)) or
    (FVideoInDevice = '') then
    FVideoInDevice := ApdNoTerminalName
  else
    FVideoInDevice := ApdDefaultTerminalName;
end;

procedure TApdCustomVoIP.SetVideoOutDevice(const Value: TWinControl);
  { VideoOutWindow write access method }
begin
  FVideoOutWindow := Value;
end;

procedure TApdCustomVoIP.SetVideoOutWindowAutoSize(const Value: Boolean);
begin
  { NOTE: Setting this property while stream is being rendered not supported }
  FVideoOutWindowAutoSize := Value;
end;

function TApdCustomVoIP.ShowMediaSelectionDialog: Boolean;
  { display the media selection dialog to select the audio/video in/out devices }
begin
  if not FVoIPAvailable then
    raise EVoIPNotSupported.CreateUnknown(sVoIPNotAvailable, 0);

  Result := EditVoIPAudioVideo(Self, Name);
end;

procedure TApdCustomVoIP.ShutDownTapi;
  { deallocate our TAPI hooks }
begin
  if gpCall <> nil then begin
    gpCall := nil;
  end;

  if gpTapi <> nil then begin
    gpTapi.Shutdown;
  end;
end;

procedure TApdCustomVoIP.WndProc(var Message: TMessage);
  { message handler }
begin
  case Message.Msg of
    apw_VoIPNotifyMessage : {message sent by event sink }
      begin
        ProcessTapiEvent(TAPI_EVENT(Message.wParam), IDispatch(Message.lParam));
      end;
    apw_VoIPEventMessage  : { message sent to generate event asynchronously }
      begin
        if Message.wParam in [etDisconnected, etFail] then begin         {!!.01}
          case Message.lParam of                                         {!!.01}
            CEC_NONE                  : FErrorCode := ecOK;              {!!.01}
            CEC_DISCONNECT_BUSY       : FErrorCode := ecVoIPCallBusy;    {!!.01}
            CEC_DISCONNECT_BADADDRESS : FErrorCode := ecVoIPBadAddress;  {!!.01}
            CEC_DISCONNECT_NOANSWER   : FErrorCode := ecVoIPNoAnswer;    {!!.01}
            CEC_DISCONNECT_CANCELLED  : FErrorCode := ecVoIPCancelled;   {!!.01}
            CEC_DISCONNECT_REJECTED   : FErrorCode := ecVoIPRejected;    {!!.01}
            CEC_DISCONNECT_FAILED     : FErrorCode := ecVoIPFailed;      {!!.01}
          end;                                                           {!!.01}
        end;                                                             {!!.01}

        case Message.wParam of
          etConnect      : DoConnectEvent;
          etDisconnected : DoDisconnectEvent;
          etFail         : DoFailEvent;
          etIncomingCall : DoIncomingCallEvent;
          etStatus       : DoStatusEvent(0, 0, 0);
        end;
      end;
    WM_TIMER : { this is our ConnectTimeout timer }                      {!!.04}
      begin                                                              {!!.04}
        if Message.WParam = FConnectTimer then begin
          { ConnectTimeout seconds have elapsed, cancel the attempt }    {!!.04}
          KillTimer(FHandle, FConnectTimer);                             {!!.04}
          DisconnectTheCall;                                             {!!.04}
        end;                                                             {!!.04}                                                                    
      end;                                                               {!!.04}

    else begin               { default message processing }
      try
        Dispatch(Message);
        if Message.Msg = WM_QUERYENDSESSION then
          Message.Result := 1;
      except
        Application.HandleException(Self);
      end;

    end;
  end;
end;

{ TApdTapiEventSink }
{ the event sink is an interface that gets the TAPI events, we post a message }
{ to the TApdCustomVoIP component to handle the events asynchronously }

function TApdTapiEventSink._AddRef: Integer;
begin
  inc(FRefCount);
  Result := FRefCount;
end;

function TApdTapiEventSink._Release: Integer;
begin
  Dec(FRefCount);
  if FRefCount = 0 then begin
    Result := 0;
    Free;
  end else
    Result := FRefCount;
end;

constructor TApdTapiEventSink.Create(AOwner: TApdCustomVoIP);
begin
  FOwner := AOwner;
  FAnswer := False;
end;

function TApdTapiEventSink.Event(TapiEvent: TAPI_EVENT;
  const pEvent: IDispatch): HResult;
  { this is the event interface itself }
begin
  pEvent._AddRef;
  { post a message to our WndProc so the event sink can respond to the next }
  { event }
  PostMessage(FOwner.FHandle, apw_VoIPNotifyMessage,
    wParam(TapiEvent), lParam(pEvent));
  Result := S_OK;
end;

function TApdTapiEventSink.QueryInterface(const IID: TGUID;
  out Obj): HResult;
begin
  if (IsEqualGUID(IID, IUnknown) or IsEqualGUID(IID, IID_ITTAPIEventNotification)) then begin
    inc(FRefCount);
    if GetInterface(IID, Obj) then
      Result := S_OK else Result := E_NOINTERFACE;
  end else
    Result := E_NOINTERFACE;
end;

{ TApdVoIPLog }

procedure TApdVoIPLog.AddLogString(Verbose : Boolean; const S: string);
var
  LogStream : TFileStream;
  TimeStamp : string;
begin
  if FEnabled then
    if Verbose and FVerboseLog then begin
      if FileExists(FLogName) then
        LogStream := TFileStream.Create(FLogName, fmOpenReadWrite	or fmShareDenyNone)
      else
        LogStream := TFileStream.Create(FLogName, fmCreate or fmShareDenyNone);
      LogStream.Seek(0, soFromEnd);
      TimeStamp := FormatDateTime('dd/mm/yy : hh:mm:ss - ', Now) + S + #13#10;
      LogStream.WriteBuffer(TimeStamp[1], Length(TimeStamp));
      LogStream.Free;
    end;
end;

procedure TApdVoIPLog.ClearLog;
begin
  SysUtils.DeleteFile(FLogName);
end;

{ TApdVoIPTerminal }

function TApdVoIPTerminal.GetDeviceInUse: Boolean;
begin
  Result := FTerminalState = tsInUse;
end;

end.

⌨️ 快捷键说明

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