Pausing Lync when on a call using the Lync Client SDK
This is a simple example of how to use the Lync Client SDK to solve a small problem, which was annoying me.
Lync is pretty clever, in that when you receive a new call, it will reduce the volume of anything you’re currently listening to. However, what I’d really like Lync to do is pause the music, because I don’t want to feel like I’m having my conversations in a movie, with a soundtrack! Why not use the Lync Client SDK to monitor my presence and, when I go into a call, trigger the multimedia Play/Pause button in Windows. When I’m off the call, start the music up again.
I’m not a Developer, but I want to use this anyway
If you don’t care about how this is done, but would like it anyway, you can download the compiled application by downloading everything from /binaries and putting into a folder, then running PauseMusicOnCall.exe. Disclaimer: you really shouldn’t just download exe files from the internet without scanning them and being happy with them first. Also, this is meant to be a code sample, so the application isn’t pretty, hasn’t been tested, and isn’t guaranteed to work on your computer. I don’t have bandwidth to support it, so you’re on your own.
If you’d like more information about Lync Desktop Development, I’ve hand-selected a list of blog posts I think you’d find useful, which I’ve called the Lync Desktop Development Collection.
The Code
The code is all hosted at github.com/tomorgan/LyncPauseMusicOnCall. If someone wants to make it into a ‘proper’ application, by adding system tray support, icons, etc, that would be nice.
The first thing the application does is get a handle on the Lync Client, and subscribe to changes in status. This means that the application will be aware of when Lync is signed in, signed out, etc. Each time that changes we want to check to see if the client is signed in, and if they are, we want to subscribe to that user’s presence. Because the event handler only fires on changes (and we might have started this application after Lync was signed in) we also make an explicit call to SubscribeToPresenceIfSignedIn at this time:
_client = LyncClient.GetClient(); _client.StateChanged += _client_StateChanged; SubscribetoPresenceIfSignedIn(_client.State);
Each time the state changes, we check to see if we’re still signed in. If we are, then we do two thing. Firstly, we update a property in our view model, with the SIP address of the signed in user (self). We use this for display later on. Secondly, we subscribe to events when the contact information of the signed in user changes. This is because we want to know when the availability and activity of the user changes, so we can pick up when they’re in a call. If the client is anything other than signed in, we remove the event handler. This means that if the user signs in and out a few times, we won’t register multiple event handles:
if (state == ClientState.SignedIn) { SelfSipAddress = _client.Self.Contact.Uri; _client.Self.Contact.ContactInformationChanged += Contact_ContactInformationChanged; } else { //remove event handler (i.e. from previous logins etc) _client.Self.Contact.ContactInformationChanged -= Contact_ContactInformationChanged; }
Each time the contact information changes, the  Contact_ContactInformationChanged event fires. We can work out whether or not we’re in a call by evaluating both the Availability and the Activity of our signed in user. If the Availability is Busy and the Activity is set to “In a call” … well, that’s pretty convincing! That’s enough for us to trigger the Play/Pause button. We also track our state using a private boolean, so that when the status changes to anything else, we can trigger the button again (to resume the music), but only if we previously paused it (otherwise we’d be doing it for every other presence change!!):
private void Contact_ContactInformationChanged(object sender, ContactInformationChangedEventArgs e) { Debug.WriteLine("Contact information changed"); if (e.ChangedContactInformation.Contains(ContactInformationType.Activity) || e.ChangedContactInformation.Contains(ContactInformationType.Availability)) { var activity = _client.Self.Contact.GetContactInformation(ContactInformationType.ActivityId); ContactAvailability availability = (ContactAvailability)_client.Self.Contact.GetContactInformation(ContactInformationType.Availability); if (availability == ContactAvailability.Busy && activity.ToString().ToLower() == "on-the-phone") { if (!_pauseEnabled) { TriggerPauseButton(activity.ToString()); _pauseEnabled = true; UpdateStatus(); } } else { if (_pauseEnabled) { TriggerPauseButton(activity.ToString()); _pauseEnabled = false; UpdateStatus(); } } } }
Actually using the Windows Play/Pause button was more complicated than I thought it might be. Because it’s not supported by SendKeys, I’ve had to use keybd_event from user32.dll. StackOverflow and KbdEdit helped me a lot here.
Finally, on the UI. This application arguably doesn’t really need a user interface, but it was quicker to do it this way than create a windows service or tray-only application. I’ve used one of the built-in Lync controls to show the presence of the user (with a binding on the SIP address), and a text binding so that you can see when the application has triggered the pause button:
And that’s it. It’s simple, but it works. There are rough edges – for instance if you run in and you’re not playing music, it might try and play something when you take a call, because it’s blindly invoking the Play/Pause button – but I can live with that.
Hopefully, this will help you if you want to try out something super-simple with Lync Development. Reminder: all the code is on GitHub, so please grab it and have a play!
Great little tool! Might mess with it so it runs as a service.