using System; using System.Drawing; using System.ComponentModel; using System.Windows.Forms; using System.Threading; using System.Runtime.InteropServices; using AccCoreLib; using RTCCORELib; namespace AvTestor { class AvTestor : Control { [DllImport("acccore.dll", EntryPoint="#111", PreserveSig=false)] private static extern void AccCreateSession( [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IDispatch)] out object session); private static AvTestor avTest; private AccSession s; private IAccAvManager m_avManager; private IAccAvSession m_avSession; private IVideoWindow m_remoteVideo; [STAThread] static void Main(string[] args) { if (args.Length != 2) { Console.WriteLine("usage: acshbuddy screenname password"); return; } avTest = new AvTestor(); avTest.Run(args[0], args[1]); } private void Run(string username, string password) { try { // create control to allow invokes CreateControl(); // create and init session object o; AccCreateSession(typeof(IAccSession).GUID, out o); s = (AccSession)o; s.ClientInfo.set_Property(AccClientInfoProp.AccClientInfoProp_Description, "acshbuddy (key=ju1yztKT86VJ0xj3)"); s.Identity = username; s.SignOn(password); // event list s.OnStateChange += new DAccEvents_OnStateChangeEventHandler(s_OnStateChange); s.OnSecondarySessionStateChange += new DAccEvents_OnSecondarySessionStateChangeEventHandler(s_OnSecondarySessionStateChange); s.OnAudioLevelChange += new DAccEvents_OnAudioLevelChangeEventHandler(s_OnAudioLevelChange); s.OnAvManagerChange += new DAccEvents_OnAvManagerChangeEventHandler(s_OnAvManagerChange); s.OnAvStreamStateChange += new DAccEvents_OnAvStreamStateChangeEventHandler(s_OnAvStreamStateChange); s.OnInviteResult += new DAccEvents_OnInviteResultEventHandler(s_OnInviteResult); s.OnParticipantJoined += new DAccEvents_OnParticipantJoinedEventHandler(s_OnParticipantJoined); s.OnParticipantLeft += new DAccEvents_OnParticipantLeftEventHandler(s_OnParticipantLeft); // start main loop Application.Run(); } catch (COMException e) { Console.WriteLine(e.Message); } } // class functions to handle AV stuff private void QuitAvSession() { try { if (m_avSession != null) { bool isVideo = (bool)m_avSession.get_Property((int)AccAvSessionProp.AccAvSessionProp_Video); if (isVideo && m_remoteVideo != null) { Console.WriteLine("Start closing the Video Window and releasing the object"); m_remoteVideo.Visible = 0; m_remoteVideo = null; Console.WriteLine("Finished closing the Video Window and releasing the object"); } Console.WriteLine("Local side is quiting the AvSession"); IAccSecondarySession secSession = (IAccSecondarySession)m_avSession; object o = secSession.get_Property((int)AccSecondarySessionProp.AccSecondarySessionProp_State); AccSecondarySessionState state = (AccSecondarySessionState)o; if (state != AccSecondarySessionState.AccSecondarySessionState_Offline) m_avSession.EndSession(); m_avSession = null; } Console.WriteLine("Starting garbage collection"); GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine("Garbage collection complete"); } catch (COMException e) { Console.WriteLine(e.Message); } } private void StartAvSession(string userName, int flags) { try { if (m_avManager == null) m_avManager = (IAccAvManager)s.GetSecondaryManager((int)AccSecondarySessionServiceId.AccSecondarySessionServiceId_AudioVideo); m_avSession = m_avManager.CreateSession(userName, flags); if (flags == (int)AccAvFlags.AccAvFlags_Video) Console.WriteLine("Creating Video Session with {0}.", userName); else Console.WriteLine("Creating Audio Session with {0}.", userName); } catch (COMException e) { Console.WriteLine(e.Message); } } private void QuitAvTestor() { if (m_avSession != null) { bool isVideo = (bool)m_avSession.get_Property((int)AccAvSessionProp.AccAvSessionProp_Video); if (isVideo && m_remoteVideo != null) { Console.WriteLine("Start closing the Video Window and releasing the object"); m_remoteVideo.Visible = 0; m_remoteVideo = null; Console.WriteLine("Finished closing the Video Window and releasing the object"); } IAccSecondarySession secSession = (IAccSecondarySession)m_avSession; object o = secSession.get_Property((int)AccSecondarySessionProp.AccSecondarySessionProp_State); AccSecondarySessionState state = (AccSecondarySessionState)o; if (state != AccSecondarySessionState.AccSecondarySessionState_Offline) m_avSession.EndSession(); m_avSession = null; } m_avManager = null; s.SignOff(); Console.WriteLine("Starting garbage collection"); GC.Collect(); GC.WaitForPendingFinalizers(); Console.WriteLine("Garbage collection complete"); Application.Exit(); } private void StartMultiPartyAvSession(string roomName, int flags) { try { m_avSession = m_avManager.CreateMultipartySession(roomName, flags); Console.WriteLine("Creating Multiparty Session with roomName {0}.", roomName); } catch (COMException e) { Console.WriteLine(e.Message); } } private void InviteBuddyToSession(string userName) { if (m_avSession == null) { Console.WriteLine("Start a Multiparty Session before trying to invite someone."); return; } try { IAccSecondarySession secSession = (IAccSecondarySession)m_avSession; object o = secSession.get_Property((int)AccSecondarySessionProp.AccSecondarySessionProp_State); AccSecondarySessionState state = (AccSecondarySessionState)o; if (state != AccSecondarySessionState.AccSecondarySessionState_Online) { Console.WriteLine("Only invite a user once the Multiparty Session is online, right now the state is {0}.", state); return; } m_avSession.Invite(userName, "Please join me in this audio session"); } catch (COMException e) { Console.WriteLine(e.Message); } } private void ListUsersInSession() { try { if (m_avSession == null) { Console.WriteLine("Cannot list users without a session"); return; } Array a = (Array) m_avSession.get_Property((int)AccSecondarySessionProp.AccSecondarySessionProp_Participants); IAccParticipant[] attendees = new IAccParticipant[a.Length]; Console.WriteLine("Start reading the participant array, array contains {0} items.", a.Length); foreach ( IAccParticipant user in a ) { Console.WriteLine("Participant : {0}", user.Name); } Console.WriteLine("Finished reading the participant array, array contained {0} items.", a.Length); } catch (COMException e) { Console.WriteLine(e.Message); } } private void DumpAvManager() { // input devices Array a =(Array)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_AvailableInputDevices); string[] inDevice = new string[a.Length]; Console.WriteLine("Available InPutDevices..."); foreach (string str in a) { Console.WriteLine("InPutDevice : {0}", str); } // output devices Array a2 =(Array)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_AvailableOutputDevices); string[] outDevice = new string[a2.Length]; Console.WriteLine("Available OutPutDevices..."); foreach (string str in a2) { Console.WriteLine("OutPutDevices : {0}", str); } // video devices Array a3 =(Array)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_AvailableVideoInputDevices); string[] vidDevice = new string[a3.Length]; Console.WriteLine("Available VideoDevices..."); foreach (string str in a3) { Console.WriteLine("VideoDevices : {0}", str); } // echo cancelation Console.WriteLine("Echo Cancelation is {0}", (bool)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_EchoCancellation)); // input device Console.WriteLine("Default Input device is {0}", (string)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_InputDevice)); // library name Console.WriteLine("Library name is {0}", (string)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_LibraryName)); // library version Console.WriteLine("Library Version is {0}", (UInt32)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_LibraryVersion)); // max bitrate Console.WriteLine("Max Bitrate is {0}", (Int32)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_MaxBitrate)); // output device Console.WriteLine("Default Output device is {0}", (string)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_OutputDevice)); // video device Console.WriteLine("Default Video device is {0}", (string)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_VideoInputDevice)); // Windows Audio Input device Console.WriteLine("Default Windows Audio Input device is {0}", (string)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_WindowsAudioInputDevice)); // Windows Audio Output device Console.WriteLine("Default Windows Audio Output device is {0}", (string)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_WindowsAudioOutputDevice)); // Windows Voice Input device Console.WriteLine("Default Windows Voice Input device is {0}", (string)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_WindowsVoiceInputDevice)); // Windows Voice Output device Console.WriteLine("Default Windows Voice Output device is {0}", (string)m_avManager.get_Property(AccAvManagerProp.AccAvManagerProp_WindowsVoiceOutputDevice)); } private void ShowVideoWindow(string userName) { m_remoteVideo = (IVideoWindow)m_avSession.GetVideoWindow(userName); m_remoteVideo.Visible = -1; return; } private void LoadAvManager() { try { if (m_avManager == null) m_avManager = (IAccAvManager)s.GetSecondaryManager((int)AccSecondarySessionServiceId.AccSecondarySessionServiceId_AudioVideo); } catch (COMException e) { Console.WriteLine(e.Message); } } // IM Events to handle AV private void s_OnStateChange(AccSession session, AccSessionState State, AccResult hr) { switch (State) { case AccSessionState.AccSessionState_Online: Console.WriteLine("AvTestor is Online..."); LoadAvManager(); WaitForCommand(); break; case AccSessionState.AccSessionState_Offline: Console.WriteLine("AvTestor is Offline..."); Application.Exit(); break; case AccSessionState.AccSessionState_Connecting: Console.WriteLine("AvTestor is connecting..."); break; default: Console.WriteLine("AvTestor is {0}", State); break; } } private void s_OnSecondarySessionStateChange(AccSession session, IAccSecondarySession secondarySession, AccSecondarySessionState State, AccResult hr) { // only handle av sessions. object type = secondarySession.get_Property((int)AccSecondarySessionProp.AccSecondarySessionProp_ServiceId); AccSecondarySessionServiceId id = (AccSecondarySessionServiceId)type; if (id != AccSecondarySessionServiceId.AccSecondarySessionServiceId_AudioVideo) secondarySession.Reject((int)AccResult.ACC_E_USER_NOT_CAPABLE); switch (State) { case AccSecondarySessionState.AccSecondarySessionState_Online: { Console.WriteLine("AvTestor has a secondary session state online."); // if video then we need to show the video window bool isVideo = (bool)m_avSession.get_Property((int)AccAvSessionProp.AccAvSessionProp_Video); if (isVideo) ShowVideoWindow((string)secondarySession.get_Property((int)AccSecondarySessionProp.AccSecondarySessionProp_RemoteUserName)); } break; case AccSecondarySessionState.AccSecondarySessionState_Offline: QuitAvSession(); Console.WriteLine("AvTestor has a secondary session state offline."); break; case AccSecondarySessionState.AccSecondarySessionState_Connecting: Console.WriteLine("AvTestor has a secondary session state connecting."); break; case AccSecondarySessionState.AccSecondarySessionState_Paused: Console.WriteLine("AvTestor has a secondary session state paused."); break; case AccSecondarySessionState.AccSecondarySessionState_ReceivedProposal: Console.WriteLine("AvTestor has a secondary session state received proposal."); break; case AccSecondarySessionState.AccSecondarySessionState_SentProposal: Console.WriteLine("AvTestor has a secondary session state sent proposal."); break; } } private void s_OnAudioLevelChange(AccSession session, IAccAvSession avSession, string userName, int level) { } private void s_OnAvManagerChange(AccSession session, IAccAvManager avManager, AccAvManagerProp prop, AccResult hr) { Console.WriteLine("{0} has changed in the av manager with result {1}.", prop, hr); } private void s_OnAvStreamStateChange(AccSession session, IAccAvSession avSession, string userName, AccAvStreamType stream, AccSecondarySessionState State, AccResult hr) { } private void s_OnInviteResult(AccSession session, IAccSecondarySession secondarySession, string userName, int transId, AccResult hr) { Console.WriteLine("The invite to {0} has a result of {1}.", userName, hr); } private void s_OnParticipantJoined(AccSession session, IAccSecondarySession secondarySession, IAccParticipant participant) { Console.WriteLine("{0} has joined the av session.", participant.Name); } private void s_OnParticipantLeft(AccSession session, IAccSecondarySession secondarySession, IAccParticipant participant, AccResult method, string by, string reason) { Console.WriteLine("{0} has left the av session with method, {1}, by {2}, for reason {3}.", participant.Name, method, by, reason); } // input handler class class InputEvent : System.EventArgs { public InputEvent(string incommand) { command = incommand; } public string Command { get { return command; } } private readonly string command; }; private delegate void InputHandler(object o, InputEvent e); private void WaitForCommand() { MethodInvoker mi = new MethodInvoker(GetCommand); mi.BeginInvoke(null, null); } private void GetCommand() { string command = Console.ReadLine(); InputEvent e = new InputEvent(command); object[] list = { this, e }; BeginInvoke(new InputHandler(HandleCommand), list); } private void HandleCommand(object o, InputEvent e) { string[] tokens = e.Command.Split(' '); string verb = tokens[0]; switch (verb) { case ":q": QuitAvTestor(); break; case "av:sa": if (tokens.Length != 2) { Console.WriteLine("Usage... av:sa buddy"); break; } StartAvSession(tokens[1], 0); break; case "av:sv": if (tokens.Length != 2) { Console.WriteLine("Usage... av:sv buddy"); break; } StartAvSession(tokens[1], (int)AccAvFlags.AccAvFlags_Video); break; case "av:sm": if (tokens.Length != 2) { Console.WriteLine("Usage... av:sm sessionName"); break; } StartMultiPartyAvSession(tokens[1], 0); break; case "av:i": if (tokens.Length != 2) { Console.WriteLine("Usage... av:i userName"); break; } InviteBuddyToSession(tokens[1]); break; case "av:lu": ListUsersInSession(); break; case "av:dm": DumpAvManager(); break; case "av:q": QuitAvSession(); break; case "av:l": //ListCustomSessions(); break; case ":h": Console.WriteLine("av:sa {buddy name} start audio"); Console.WriteLine("av:sv {buddy name} start video"); Console.WriteLine("av:i {buddy name} invite user to a multiparty session"); Console.WriteLine("av:lu list users in a session"); Console.WriteLine("av:sv {session name} start multiparty audio"); Console.WriteLine("av:dm dump all the properties from the av manager"); Console.WriteLine("av:q quits the audio or video session"); Console.WriteLine(":q signs off of AIM and quits the test application"); break; case "o:v": Console.WriteLine("Client Version: AvTestor 1.0"); break; default: Console.WriteLine("Invalid command"); Console.WriteLine(":h for list of commands"); break; } WaitForCommand(); } } }