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

📄 advoip.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
(***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is TurboPower Async Professional
 *
 * The Initial Developer of the Original Code is
 * TurboPower Software
 *
 * Portions created by the Initial Developer are Copyright (C) 1991-2002
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** *)

{*********************************************************}
{*                    ADVOIP.PAS 4.06                    *}
{*********************************************************}
{* TApdVoIP component, provides access to Voice over IP  *}
{*       (IP Telephony) via TAPI 3 and DirectShow        *}
{*********************************************************}

{Global defines potentially affecting this unit}
{$I AWDEFINE.INC}


{ The TApdVoIP component does not have the complete functionality as described }
{ in the manual. Where possible, those items are annotated in the source with  }
{ "NOTE:" comments. These deficiencies will be addressed in future minor point }
{ releases.  The most obvious buglet is that we will use the default video-in  }
{ device, the local camera that captures video for transmission to the remote. }
{ TAPI 3.0 does not provide a robust mechanism for selecting a specific video  }
{ terminal, so we use whatever the default video device is. TAPI 3.1 (XP) does }
{ have the functionality built in to select the video-in device. TAPI 3.0 also }
{ did not have functional conferencing capabilities, so they are not included  }
{ here.  3.1 supposedly does have functional conferencing.                     }

{!!.01} { changes include cleanup of code }
unit AdVoIP;

interface

uses
  {$IFDEF Delphi5}
  OleServer,
  {$ELSE}
  OleCtrls,
  {$ENDIF}
  SysUtils, ActiveX, Classes, Windows, Controls, ComObj, Messages, Forms,
  { APRO units }
  OOMisc,
  AdExcept,
  AdITapi3;  { TAPI 3 abbreviated type library }

type

  {TApdTerminal enumerations}
  TApdTerminalDeviceClass = (dcHandsetTerminal, dcHeadsetTerminal,
                             dcMediaStreamTerminal, dcMicrophoneTerminal,
                             dcSpeakerPhoneTerminal, dcSpeakersTerminal,
                             dcVideoInputTerminal, dcVideoWindowTerminal);
  TApdTerminalMediaType   = (mtAudio, mtVideo, mtDataModem, mtG3_Fax);
  TApdMediaDirection      = (mdCapture, mdRender, mdBiDirectional);
  TApdTerminalType        = (ttStatic, ttDynamic);
  TApdTerminalState       = (tsInUse, tsNotInUse);

  TApdDisconnectCode      = (dcNormal, dcNoAnswer, dcRejected);
  TApdQOSServiceLevel     = (qsBestEffort, qsIfAvailable, qsNeeded);
  TApdFinishMode          = (fmAsTransfer, fmAsConference);
  TApdCallState           = (csIdle, csInProgress, csConnected, csDisconnected,
                             csOffering, csHold, csQueued);
  TApdAddressType         = (atPhoneNumber, atSDP, atEmailName, atDomainName,
                             atIPAddress);

  TApdCallPriviledge      = (cpOwner, cpMonitor);

  TApdCallInfoLong = (cilMediaTypesAvailable, cilBearerMode,
                   cilCallerIDAddressType, cilCalledIDAddressType,
                   cilConnectedIDAddressType, cilRedirectionIDAddressType,
                   cilRedirectingIDAddresstype, cilOrigin, cilReason,
                   cilAppSpecific, cilCallParamsFlags, cilCallTreatment,
                   cilMinRate, cilMaxRate, cilCountryCode, cilCallID,
                   cilRelatedCallID, cilCompletionID, cilNumberOfOwners,
                   cilNumberOfMonitors, cilTrunk, cilRate);

  TApdCallInfoType = (cisCallerIDName, cisCallerIDNumber, cisCalledIDName,
                   cisCalledIDNumber, cisConnectedIDName,
                   cisConnectedIDNumber, cisRedirectionIDName,
                   cisRedirectionIDNumber, cisRedirectingIDName,
                   cisRedirectingIDNumber, cisCalledPartyFriendlyName,
                   cisComment, cisDisplayableAddress, cisCallingPartyID);

  TApdCallInfoBufferType = (cibUserUserInfo, cibDevSpecificBuffer,
                         cibCallDataBuffer, cibChargingInfoBuffer,
                         cibHighLevelCompatibilityBuffer,
                         cibLowLevelCompatibilityBuffer);

  TApdAddressState = (asInService, asOutOfService);
  TApdCallHubState = (chsActive, chsIdle);


  {forwards}
  TApdCustomVoIP = class;

  {event declarations}
  TApdVoIPNotifyEvent = procedure(VoIP: TApdCustomVoIP) of object;
  TApdVoIPFailEvent = procedure(VoIP : TApdCustomVoIP;
                                ErrorCode : Integer) of object;
  TApdVoIPIncomingCallEvent = procedure(VoIP : TApdCustomVoIP;
                                        CallerAddr: string;
                                        var Accept : Boolean) of object;
  TApdVoIPStatusEvent = procedure(VoIP : TApdCustomVoIP;
                                  TapiEvent, Status, SubStatus : Word) of object;

  { TApdCallInfo - used to hold common ITCallInfo data }
  TApdVoIPCallInfo = record
    InfoAvailable : Boolean;       { True if we get the info, False if the }
                                   { ITCallInfo interface isn't available  }
    { string type fields }
    CallerIDName,                  { the name of the caller }
    CallerIDNumber,                { the number of the caller }
    CalledIDName,                  { the name of the called location }
    CalledIDNumber,                { the number of the called location }
    ConnectedIDName,               { the name of the connected location }
    ConnectedIDNumber,             { the number of the connected location }
    CalledPartyFriendlyName,       { the called party friendly name }
    Comment,                       { a comment about the call provided by the originator }
    DisplayableAddress,            { a displayable version of the called or calling address }
    CallingPartyID : string;       { the identifier of the calling party }
    { DWORD types }
    MediaTypesAvailable,           { the media types available on the call (TAPIMEDIATYPE_*) }
    CallerIDAddressType,           { the address types (LINEADDRESSTYPE_*) }
    CalledIDAddressType,
    ConnectedIDAddressType,
    Origin,                        { the origin of the call (LINECALLORIGIN_*) }
    Reason,                        { the reason for the call (LINECALLREASON_*) }
    MinRate,                       { the minimun data rate in bps }
    MaxRate,                       { the maximum data rate in bps }
    Rate : DWORD;                  { the current rate of the call in bps }
  end;

  {TApdTerminals}
  TApdTerminals = class(TCollection)
  end;

  { TAPI3 event notification sink }
  TApdTapiEventSink = class(TObject, IUnknown, ITTAPIEventNotification)
  private
    FRefCount : Integer;
    FOwner    : TApdCustomVoIP;
    FAnswer   : Boolean;
  public
    constructor Create(AOwner : TApdCustomVoIP);

    {IUnknown}
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;

    {ITTAPIEventNotification}
    function Event(TapiEvent: TAPI_EVENT; const pEvent: IDispatch): HResult; stdcall;
  end;

  {TApdVoIPTerminal}
  TApdVoIPTerminal = class(TCollectionItem)
  private
    FTerminalDeviceClass : TApdTerminalDeviceClass;
    FDeviceName          : string;
    FMediaDirection      : TApdMediaDirection;
    FMediaType           : TApdTerminalMediaType;
    FTerminalType        : TApdTerminalType;
    FTerminalState       : TApdTerminalState;
    function GetDeviceInUse: Boolean;
  published
    property DeviceClass : TApdTerminalDeviceClass
      read FTerminalDeviceClass;
    property DeviceInUse : Boolean
      read GetDeviceInUse;
    property DeviceName : string
      read FDeviceName;
    property MediaDirection : TApdMediaDirection
      read FMediaDirection;
    property MediaType : TApdTerminalMediaType
      read FMediaType;
    property TerminalType : TApdTerminalType
      read FTerminalType;
    property TerminalState : TApdTerminalState
      read FTerminalState;
  end;

  { Undocumented log class. Set LogName to the path\name where you want the  }
  { log to be written. VerboseLog determines whether only major events (such }
  { as when a call is connected or disconnected) happens, or whether more    }
  { detail is desired. Enabled toggles whether the log strings are added or  }
  { not. The log file is updated whenever AddLogString is called. ClearLog   }
  { will delete the log file without prompting }
  TApdVoIPLog = class(TPersistent)
  private
    FVerboseLog: Boolean;
    FEnabled: Boolean;
    FLogName: string;
    public
      procedure AddLogString(Verbose : Boolean; const S : string);
      procedure ClearLog;
    published
      property LogName : string
        read FLogName write FLogName;
      property VerboseLog : Boolean
        read FVerboseLog write FVerboseLog;
      property Enabled : Boolean
        read FEnabled write FEnabled;
  end;

  TApdCustomVoIP = class(TApdBaseComponent)
  private
    FWaitingForCall: Boolean;
    FConnected: Boolean;
    FAudioInDevice: string;
    FVideoInDevice: string;
    FCallerIDName: string;
    FAudioOutDevice: string;
    FCallerIDNumber: string;
    FAvailableTerminalDevices: TApdTerminals;
    FOnFail: TApdVoIPFailEvent;
    FOnIncomingCall: TApdVoIPIncomingCallEvent;
    FOnDisconnect: TApdVoIPNotifyEvent;
    FOnConnect: TApdVoIPNotifyEvent;
    FOnStatus: TApdVoIPStatusEvent;
    FVideoOutWindow: TWinControl;
    FPreviewWindow: TWinControl;
    FEnablePreview: Boolean;
    FEnableVideo: Boolean;
    FVideoOutWindowAutoSize: Boolean;
    FPreviewWindowAutoSize: Boolean;
    FEventLog: TApdVoIPLog;
    FVoIPAvailable: Boolean;
    FCallerDisplayName: string;
    FCallComment: string;
    FCallDisplayableAddress: string;
    FCallCallingPartyID: string;
    FConnectTimeout: Integer;                                            {!!.04}

    { property access methods }
    function GetCallInfo: TApdVoIPCallInfo;
    procedure SetPreviewWindow(const Value: TWinControl);
    procedure SetVideoOutDevice(const Value: TWinControl);
    procedure SetEnablePreview(const Value: Boolean);
    procedure SetVideoInDevice(const Value: string);
    procedure SetAudioInDevice(const Value: string);
    procedure SetAudioOutDevice(const Value: string);
    procedure SetEnableVideo(const Value: Boolean);
    procedure SetVideoOutWindowAutoSize(const Value: Boolean);
    procedure SetPreviewWindowAutoSize(const Value: Boolean);
    function GetCallInfoInterface: ITCallInfo;
  protected
    { global interfaces }
    gpTapi : ITTapi;             { the TAPI interface }
    gpCall : ITBasicCallControl; { the call interface }
    gpAddress : ITAddress;       { the address interface (the H323 device) }
    gulAdvise : LongInt;
    gpTAPIEventNotification : TApdTapiEventSink;
    NotifyRegister : Integer;    { handle to the notification callback }

    FHandle : HWND;              { handle to our wndproc }
    FErrorCode : Integer;        { the last error value }
    FTapiInitialized : Boolean;  { initialized or not }
    FConnectTimer : Integer;     { Timer used to control connect wait }  {!!.04}

    { event generation methods }
    procedure DoConnectEvent;
    procedure DoDisconnectEvent;
    procedure DoFailEvent;
    procedure DoIncomingCallEvent;
    procedure DoStatusEvent(TapiEvent, Status, SubStatus : Word);

    { our message handler }
    procedure WndProc(var Message : TMessage);
    procedure ProcessTapiEvent(TapiEvent: TAPI_EVENT; pEvent: IDispatch);

    { control methods }
    function AddressSupportsMediaType(pAddress : ITAddress;
      lMediaType : TOleEnum) : Boolean;
      { determines if the address (H323 line) supports the media type }
    function AnswerTheCall : HRESULT;
      { answer the call, called after the OnIncomingCall event is generated }
    function DetermineAddressType(const Addr : string) : Cardinal;
      { figure out if the destination address is an IP or machine name }
    function DisconnectTheCall : HRESULT;
      { terminates a call, called from CancelCall }
    function EnablePreviewWindow(pAddress : ITAddress;
      pStream : ITStream) : HRESULT;
      { associates the outbound video stream with a local preview window }
    function FindTerminal(DevName : string; MediaType : TOleEnum;
      MediaDir : TOleEnum; var ppTerminal : ITTerminal) : HRESULT;
      { finds a terminal, used to select a specific audio device }
    function FindTheAddress : HRESULT;
      { finds the H323 line address }
    function GetTerminal(pAddress : ITAddress; pStream : ITStream;
      var ppTerminal : ITTerminal) : HRESULT;
      { gets a terminal associated with the given stream }
    function GetVideoRenderTerminal(pAddress : ITAddress;
      var ppTerminal : ITTerminal) : HRESULT;
      { associates the outbound video stream with the terminal }
    function GetVideoRenderTerminalFromStream(
      pCallMediaEvent : ITCallMediaEvent; var ppTerminal : ITTerminal;
      var pfRenderStream : Boolean) : HRESULT;
      { associates the stream with a terminal }
    procedure HostWindow(pVideoWindow : IVideoWindow; IsRenderStream : Boolean);
      { sets up the preview and video render windows }
    function InitializeTapi : HRESULT;
      { initializes TAPI3 }
    function IsAudioCaptureStream(pStream : ITStream) : Boolean;
      { determines if the stream is an audio capture (outbound from mic.) stream }
    function IsAudioRenderStream(pStream : ITStream) : Boolean;
      { determines if the stream is an audio render (inbound to speakers) stream }
    function IsVideoCaptureStream(pStream : ITStream) : Boolean;
      { determines if the stream is a video capture (send video from camera) stream }
    function IsVideoRenderStream(pStream : ITStream) : Boolean;
      { determines if the stream is a video capture (inbound from remote) stream }
    procedure LoadTerminals;
      { Enumerates terminals for the AvailableTerminaDevices collection }
    function MakeTheCall (dwAddressType : DWORD;
      szAddressToCall : WideString) : Boolean;
      { Makes an outbound call }
    function RegisterTapiEventInterface : HRESULT;

⌨️ 快捷键说明

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