private void btnDelete_Click(object sender, RoutedEventArgs e) { RecordingFile file = lsvFiles.SelectedItem as RecordingFile; if (file == null) { return; } _recording.RemoveRecordingFile(file); }
/// <summary> /// Download the recording file. /// </summary> /// <param name="recordingFile">The recording file to download.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// The <see cref="Stream"/> containing the file. /// </returns> public async Task <Stream> DownloadFileAsync(RecordingFile recordingFile, CancellationToken cancellationToken = default) { var tokenHandler = _client.Filters.OfType <ITokenHandler>().SingleOrDefault(); var requestUri = recordingFile.DownloadUrl; if (tokenHandler != null) { requestUri += "?access_token=" + tokenHandler.Token; } var response = await _client.BaseClient.GetAsync(requestUri, cancellationToken).ConfigureAwait(false); return(await response.Content.ReadAsStreamAsync()); }
private void btnPlay_Click(object sender, RoutedEventArgs e) { if (lsvFiles.SelectedItem == null) { return; } RecordingFile file = lsvFiles.SelectedItem as RecordingFile; if (file == null) { return; } FilePlayerWindow dialog = new FilePlayerWindow(file.Path); dialog.Owner = this; Log.Debug("btnPlay_Click__FilePlayerWindow.ShowDialog BEFORE"); dialog.ShowDialog(); Log.Debug("btnPlay_Click__FilePlayerWindow.ShowDialog AFTER"); }
/// <summary> /// Invoked when a message stanza has been received. /// </summary> /// <param name="stanza">The stanza which has been received.</param> /// <returns>true to intercept the stanza or false to pass the stanza /// on to the next handler.</returns> public bool Input(Message message) { if (message.Type == MessageType.Management) { // Do we receive an user invitation ? if (message.Data["userinvite"] != null) { XmlElement e = message.Data["userinvite"]; try { string invitationId = e.GetAttribute("id"); string action = e.GetAttribute("action"); // 'create', 'update', 'delete' string type = e.GetAttribute("type"); // 'received', 'sent' string status = e.GetAttribute("status"); // 'canceled', 'accepted' , 'pending' UserInvitation.Raise(this, new UserInvitationEventArgs(invitationId, action, type, status)); } catch (Exception) { } } // Do we receive message about conversation management else if (message.Data["conversation"] != null) { XmlElement e = message.Data["conversation"]; string conversationID = e.GetAttribute("id"); string action = e.GetAttribute("action"); // 'create', 'update', 'delete' Dictionary <string, string> data = new Dictionary <string, string>(); if (e["type"] != null) { data.Add("type", e["type"].InnerText); } if (e["peerId"] != null) { data.Add("peerId", e["peerId"].InnerText); } if (e["peer"] != null) { data.Add("jid_im", e["peer"].InnerText); } if (e["mute"] != null) { data.Add("mute", e["mute"].InnerText); } if (e["lastMessageText"] != null) { data.Add("lastMessageText", e["lastMessageText"].InnerText); } if (e["lastMessageSender"] != null) { data.Add("lastMessageSender", e["lastMessageSender"].InnerText); } if (e["lastMessageDate"] != null) { data.Add("lastMessageDate", e["lastMessageDate"].InnerText); } if (e["unreceivedMessageNumber"] != null) { data.Add("unreceivedMessageNumber", e["unreceivedMessageNumber"].InnerText); } if (e["unreadMessageNumber"] != null) { data.Add("unreadMessageNumber", e["unreadMessageNumber"].InnerText); } ConversationManagement.Raise(this, new ConversationManagementEventArgs(conversationID, action, data)); } // Do we receive message about favorite management else if (message.Data["favorite"] != null) { XmlElement e = message.Data["favorite"]; string id = e.GetAttribute("id"); string action = e.GetAttribute("action"); // 'create', 'update', 'delete' string type = e.GetAttribute("type"); // 'user', 'room', 'bot' string position = e.GetAttribute("position"); string peerId = e.GetAttribute("peer_id"); FavoriteManagement.Raise(this, new FavoriteManagementEventArgs(id, action, type, position, peerId)); } // Do we receive message about userpassword management else if (message.Data["userpassword"] != null) { XmlElement e = message.Data["userpassword"]; string action = e.GetAttribute("action"); // 'update' only ? if (action == "update") { PasswordUpdated.Raise(this, new EventArgs()); } } // Do we receive message about room/bubble management else if (message.Data["room"] != null) { XmlElement e = message.Data["room"]; string roomId = e.GetAttribute("roomid"); string roomJid = e.GetAttribute("roomjid"); string userJid = e.GetAttribute("userjid"); // Not empty if user has been accepted / invited / unsubscribed / deleted string status = e.GetAttribute("status"); // Not empty if user has been accepted / invited / unsubscribed / deleted string privilege = e.GetAttribute("privilege"); // Not empty if user has changed it's role: user / moderator / guest string topic = e.GetAttribute("topic"); // Not empty if room updated string name = e.GetAttribute("name"); // Not empty if room updated string lastAvatarUpdateDate = e.GetAttribute("lastAvatarUpdateDate"); // Not empty if avatar has been updated. if deleted "null" string string avatarAction = ""; if (e["avatar"] != null) { avatarAction = e["avatar"].GetAttribute("action"); } RoomManagement.Raise(this, new RoomManagementEventArgs(roomId, roomJid, userJid, status, privilege, name, topic, lastAvatarUpdateDate, avatarAction)); } // Do we receive message about visualvoicemail else if (message.Data["visualvoicemail"] != null) { // WE DO NOTHING HERE // WE USE "file" message and file descrptior to manage voice message //XmlElement e = message.Data["visualvoicemail"]; //string msgId = e.GetAttribute("msgid"); //string action = e.GetAttribute("action"); //string fileId = e["fileid"]?.InnerText; //string url = e["url"]?.InnerText; //string mimeType = e["mime"]?.InnerText; //string fileName = e["filename"]?.InnerText; //string size = e["size"]?.InnerText; //string md5 = e["md5sum"]?.InnerText; //string duration = e["duration"]?.InnerText; ////log.LogDebug("duration:[{0}]", duration); //VoiceMailManagement.Raise(this, new VoiceMailManagementEventArgs(msgId, fileId, action, url, mimeType, fileName, size, md5, duration)); } // Do we receive message about file else if (message.Data["file"] != null) { XmlElement e = message.Data["file"]; string action = e.GetAttribute("action"); string fileId = e["fileid"]?.InnerText; FileManagement.Raise(this, new FileManagementEventArgs(fileId, action)); } // Do we receive message about thumbnail else if (message.Data["thumbnail"] != null) { XmlElement e = message.Data["thumbnail"]; string fileId = e["fileid"]?.InnerText; string widthStr = e["originalwidth"]?.InnerText; string heightStr = e["originalheight"]?.InnerText; int width = 0; int height = 0; try { int.TryParse(widthStr, out width); int.TryParse(heightStr, out height); } catch (Exception exc) { log.LogWarning("[Input] Exception occurred for thumbnail: [{0}]", Util.SerializeException(exc)); } ThumbnailManagement.Raise(this, new ThumbnailEventArgs(fileId, width, height)); } else if (message.Data["channel"] != null) { XmlElement e = message.Data["channel"]; string jid = message.To.GetBareJid().ToString(); string channelId = e.GetAttribute("channelid"); string action = ""; string type = ""; // Check avatar node if (e["avatar"] != null) { type = "avatar"; action = e["avatar"].GetAttribute("action"); } else { action = e.GetAttribute("action"); if (e["type"] != null) { type = e["type"].InnerText; } } ChannelManagement.Raise(this, new ChannelManagementEventArgs(jid, channelId, action, type)); } else if (message.Data["channel-subscription"] != null) { XmlElement e = message.Data["channel-subscription"]; string jid = e.GetAttribute("jid"); string channelId = e.GetAttribute("channelid"); string action = e.GetAttribute("action"); string type = ""; // Never Type info receive in this case ChannelManagement.Raise(this, new ChannelManagementEventArgs(jid, channelId, action, type)); } else if (message.Data["group"] != null) { XmlElement e = message.Data["group"]; GroupManagement.Raise(this, new MessageEventArgs(e.ToXmlString())); } else if (message.Data["recordingfile"] != null) { XmlElement e = message.Data["recordingfile"]; RecordingFile.Raise(this, new MessageEventArgs(e.ToXmlString())); } else { log.LogInformation("[Input] Message not managed"); } // Since it's a Management message, we prevent next handler to parse it return(true); } else if (message.Type == MessageType.Chat) { if (message.Data["x", "jabber:x:conference"] != null) { XmlElement e; String roomId, roomJid, roomName; String userid, userjid, userdisplayname; String subject; userid = userjid = userdisplayname = ""; subject = ""; e = message.Data["x", "jabber:x:conference"]; roomId = e.GetAttribute("roomid"); if (String.IsNullOrEmpty(roomId)) { roomId = e.GetAttribute("thread"); } roomJid = e.GetAttribute("jid"); roomName = e.GetAttribute("name"); e = message.Data["x", "jabber:x:bubble:conference:owner"]; if (e != null) { userid = e.GetAttribute("userid"); userjid = e.GetAttribute("jid"); userdisplayname = e.GetAttribute("displayname"); } e = message.Data["subject"]; if (e != null) { subject = e.InnerText; } // Since it's a room invitation, we prevent next handler to parse it RoomInvitation.Raise(this, new RoomInvitationEventArgs(roomId, roomJid, roomName, userid, userjid, userdisplayname, subject)); return(true); } } else if (message.Type == MessageType.Headline) { // Do we receive an event of pubsub type ? if (message.Data["event", "http://jabber.org/protocol/pubsub#event"] != null) { XmlElement e = message.Data["event", "http://jabber.org/protocol/pubsub#event"]; if (e["items"] != null) { ChanneItemManagement.Raise(this, new MessageEventArgs(e["items"].ToXmlString())); return(true); } else if (e["update"] != null) { ChanneItemManagement.Raise(this, new MessageEventArgs(e["update"].ToXmlString())); return(true); } } } // Pass the message on to the next handler. return(false); }
/// <summary> /// Download the recording file. /// </summary> /// <param name="cloudRecordingsResource">The cloud recordings resource.</param> /// <param name="recordingFile">The recording file to download.</param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns> /// The <see cref="Stream"/> containing the file. /// </returns> public static Task <Stream> DownloadFileAsync(this ICloudRecordings cloudRecordingsResource, RecordingFile recordingFile, CancellationToken cancellationToken = default) { return(cloudRecordingsResource.DownloadFileAsync(recordingFile.DownloadUrl)); }
private void WorkerThread() { RecordingFile file = new RecordingFile(settings); Dictionary <string, RecordHeader> recordingCameras = new Dictionary <string, RecordHeader>(); while (true) { var frame = queue.Take(); if (frame == null) { break; } if (frame.Identifier != null) { RecordHeader currentHeader; if (!recordingCameras.ContainsKey(frame.Identifier)) { currentHeader = new RecordHeader() { Identifier = frame.Identifier }; recordingCameras.Add(frame.Identifier, currentHeader); } else { currentHeader = recordingCameras[frame.Identifier]; } if (frame.TagInfo != null) { currentHeader.Tags.Add(frame.TagInfo); } if (frame.RawFrame is FrameSetEvent frameSet) { currentHeader.Tags.Add(new Tag() { Name = "PPS", Timestamp = DateTime.MinValue, Data = frameSet.StreamInfo.Pps }); currentHeader.Tags.Add(new Tag() { Name = "SPS", Timestamp = DateTime.MinValue, Data = frameSet.StreamInfo.Sps }); currentHeader.FrameData = frameSet.RawFrames; currentHeader.Timestamp = frameSet.StartTimestamp; currentHeader.Duration = frameSet.EndTimestamp - frameSet.StartTimestamp; file.SaveHeader(currentHeader); // Reset our current header recordingCameras[currentHeader.Identifier] = new RecordHeader() { Identifier = currentHeader.Identifier }; } } if (frame.Search != null) { // TODO: Should this be a separate thread? var seeking = file.Oldest; if (frame.Search.Start != null) { while ((seeking != null) && (seeking.Timestamp < frame.Search.Start)) { seeking = file.GetHeader((UInt32)seeking.NextHeader); } } Dictionary <string, DateTime> foundEnds = new Dictionary <string, DateTime>(); while (seeking != null) { if ((frame.Search.End != null) && (seeking.Timestamp > frame.Search.End)) { break; } file.LoadData(seeking, RecordHeader.LoadedParts.Identifier | RecordHeader.LoadedParts.Tags); if ((frame.Identifier == null) || frame.Identifier.Equals(seeking.Identifier)) { bool doStart = true; if (foundEnds.ContainsKey(seeking.Identifier)) { DateTime lastTime = foundEnds[seeking.Identifier]; if (seeking.Timestamp != lastTime) { frame.Search.Callback.VideoStops(settings.Identifier, seeking.Identifier, lastTime); } else { doStart = false; } } if (doStart) { frame.Search.Callback.VideoStarts(settings.Identifier, seeking.Identifier, seeking.Timestamp); } foreach (var tag in seeking.Tags) { frame.Search.Callback.VideoTag(settings.Identifier, seeking.Identifier, tag.Timestamp, tag.Name, tag.Data); } foundEnds[seeking.Identifier] = seeking.Timestamp + seeking.Duration; } seeking = (seeking.NextHeader == -1) ? null : file.GetHeader((UInt32)seeking.NextHeader); } foreach (KeyValuePair <string, DateTime> kvp in foundEnds) { frame.Search.Callback.VideoStops(settings.Identifier, kvp.Key, kvp.Value); } frame.Search.Callback.VideoSearched(settings.Identifier); } if (frame.Streamer != null) { if (frame.Streamer.CurrentHeader == null) { frame.Streamer.CurrentHeader = file.Oldest; } while ((frame.Streamer.CurrentHeader != null) && ((frame.Streamer.CurrentHeader.Timestamp < frame.Streamer.StartTime) || (frame.Streamer.CurrentHeader.Identifier != frame.Streamer.Identifier))) { frame.Streamer.CurrentHeader = file.GetHeader((UInt32)frame.Streamer.CurrentHeader.NextHeader); } frame.Streamer.Step(); } } file.Stop(); }