/// <summary> /// the current session disconnected /// </summary> void OnSessionDisconnect(MiracastReceiverSession sender, MiracastReceiverDisconnectedEventArgs args) { Log("current session disconnected, creating new session..."); if (AutoStartNewSession) { StartNewSession(); } }
/// <summary> /// a new connection was created /// </summary> void OnSessionConnectionCreated(MiracastReceiverSession sender, MiracastReceiverConnectionCreatedEventArgs args) { //configure connection CurrentConnection = args.Connection; CurrentConnection.InputDevices.Keyboard.TransmitInput = false; //send pin event if (!string.IsNullOrWhiteSpace(args.Pin)) { PinAvailable?.Invoke(CurrentConnection.Transmitter.Name, args.Pin); } //start timeout task currentConnectionTimeoutCancellation = new CancellationTokenSource(); if (DeadConnectionTimeout > 0) { Task.Run(async() => { try { //wait until timeout await Task.Delay(DeadConnectionTimeout, currentConnectionTimeoutCancellation.Token); //check if a media player was created if (currentPlayer == null) { //no media source was created, kill connection Log($"no media player was created, killing connection to {CurrentConnection?.Transmitter?.MacAddress}"); Invoke(() => { StartNewSession(); }); return; } //connection looks fine to me Log("connection looks healthy, timeout task will now shut down."); } catch (TaskCanceledException) { //timeout was cancelled Log("connection timeout was cancelled"); } }); } //log details Log($"new connection created with {CurrentConnection.Transmitter.Name} ({CurrentConnection.Transmitter.MacAddress}). Auth pin is {(string.IsNullOrWhiteSpace(args.Pin) ? "No Pin" : args.Pin)}"); }
/// <summary> /// end the current cast session, and call CastEnd event /// </summary> /// <param name="sendEvent">should CastEnd be called?</param> void EndCurrentSession(bool sendEvent) { currentPlayer?.Pause(); currentPlayer?.Dispose(); currentPlayer = null; CurrentConnection?.Disconnect(MiracastReceiverDisconnectReason.Finished); CurrentConnection = null; currentSession?.Dispose(); currentSession = null; if (sendEvent) { CastEnd?.Invoke(); } }
/// <summary> /// ends the old cast session and starts a new one /// </summary> public SessionStartResult StartNewSession() { //check receiver was initialized if (castReceiver == null) { throw new InvalidOperationException("Miracast receiver was not yet initialized! Call InitReceiver first."); } //end old cast session if (currentSession != null) { EndCurrentSession(true); } //init cast session, allow takeover currentSession = castReceiver.CreateSession(/*MainView*/ null); currentSession.AllowConnectionTakeover = true; currentSession.MaxSimultaneousConnections = 1; //register event currentSession.ConnectionCreated += OnSessionConnectionCreated; currentSession.MediaSourceCreated += OnSessionMediaSourceCreated; currentSession.Disconnected += OnSessionDisconnect; //start receive on session MiracastReceiverSessionStartResult startResult = currentSession.Start(); Log($"new miracast session initialized. result: {startResult.Status} ({(startResult.ExtendedError == null ? "No Error" : startResult.ExtendedError.ToString())})"); //return correct result, end session if init failed switch (startResult.Status) { case MiracastReceiverSessionStartStatus.Success: return(SessionStartResult.Success); case MiracastReceiverSessionStartStatus.MiracastNotSupported: EndCurrentSession(false); return(SessionStartResult.MiracastNotSupported); case MiracastReceiverSessionStartStatus.AccessDenied: case MiracastReceiverSessionStartStatus.UnknownFailure: default: EndCurrentSession(false); return(SessionStartResult.Failure); } }
/// <summary> /// a media source was created for the current session (start rendering to ui) /// </summary> void OnSessionMediaSourceCreated(MiracastReceiverSession sender, MiracastReceiverMediaSourceCreatedEventArgs args) { //set flag currentConnectionTimeoutCancellation?.Cancel(); //init mediaplayer currentPlayer = new UWPMediaPlayer() { Source = args.MediaSource, IsVideoFrameServerEnabled = false, AutoPlay = true, RealTimePlayback = true }; //call event CastStart?.Invoke(CurrentConnection.Transmitter.Name, currentPlayer); //start playback Log($"starting playback of {CurrentConnection.Transmitter.Name} ({CurrentConnection.Transmitter.MacAddress})"); currentPlayer.Play(); }