using System; using System.Collections.Generic; using System.Text; using System.Threading; using System.Net; using System.Net.Sockets; using System.IO; using System.Reflection; using System.Windows.Forms; using VLCdotNet; using SecureStorage; using System.Diagnostics; namespace NHT_Server { partial class ServerConnection { # region public Vareables /// /// The first and the last index of the requested Video file list. /// public int[] VideoListIDs = new int[2] { 0, 0 }; /// /// The ID of the currently requested / streaming video file. /// public int VideoFileID = 0; /// /// The Hashvalue for the requested ID. /// public string VideoFileHash = ""; # endregion # region private vareables private VLC vlc; private Storage storage; private bool Multicasting = false; private string videoFile = ""; # endregion # region events /// /// Occurs when the client requests a list of the Video files. /// public event EventHandler VideoListRequested; /// /// Raises the event. /// /// The instance containing the event data. protected virtual void OnVideoListRequested(EventArgs e) { if (VideoListRequested != null) VideoListRequested(this, e); } /// /// Occurs when the client requests a Video File. /// public event EventHandler VideoFileRequested; /// /// Raises the event. /// /// The instance containing the event data. protected virtual void OnVideoFileRequested(EventArgs e) { if (VideoFileRequested != null) VideoFileRequested(this, e); } /// /// Occurs when the client requests a Video File ID. /// public event EventHandler VideoIdRequested; /// /// Raises the event. /// /// The instance containing the event data. protected virtual void OnVideoIdRequested(EventArgs e) { if (VideoIdRequested != null) VideoIdRequested(this, e); } # endregion /// /// If the received Command is a VideoeCommand. /// /// The received data. /// private bool VideoCommand(byte[] ReceivedData) { string command = ByteToString(ReceivedData).Substring(1, 3); switch (command) { case "001": GetVideoList(ReceivedData); return true; case "010": GetVideo(ReceivedData); return true; case "020": SeekVideo(ReceivedData); return true; case "025": StopStreaming(); return true; case "030": GetCurrentVideoTime(ReceivedData); return true; case "040": PauseStream(); return true; case "045": GetVideoHashvalue(ReceivedData); return true; default: return false; } } /// /// Sends the given ID. /// /// The ID. public void SendVideoID(int ID) { Send("4050" + ID + "#"); } /// /// Gets the hashvalue. /// /// The received data. private void GetVideoHashvalue(byte[] ReceivedData) { string AllIDs = ByteToString(ReceivedData).Substring(4); string[] IDs = AllIDs.Split('#'); if (IDs.Length > 0) { VideoFileHash = IDs[1]; OnVideoIdRequested(EventArgs.Empty); } } /// /// Pause the current stream or plays it if paused. /// private void PauseStream() { if (vlc != null) vlc.Pause(); } /// /// Gets the current video time. /// /// The received data. private void GetCurrentVideoTime(byte[] ReceivedData) { string AllIDs = ByteToString(ReceivedData).Substring(4); string[] IDs = AllIDs.Split('#'); if (IDs.Length > 0) { if (Convert.ToInt32(IDs[0]) == VideoFileID) { Send("4035" + VideoFileID + "#" + vlc.GetPositionSecs() + "#" + vlc.GetLengthSecs() + "#"); } } } /// /// Seeks the video. /// /// The received data. private void SeekVideo(byte[] ReceivedData) { string AllIDs = ByteToString(ReceivedData).Substring(4); string[] IDs = AllIDs.Split('#'); if (IDs.Length > 0) { if (Convert.ToInt32(IDs[0]) == VideoFileID) { int newPos = Convert.ToInt32(IDs[1]); if (newPos > 0 && newPos < vlc.GetLengthSecs()) SeekStream(newPos); } } } /// /// Gets the video. /// /// The received data. public void GetVideo(byte[] ReceivedData) { string AllIDs = ByteToString(ReceivedData).Substring(4); string[] IDs = AllIDs.Split('#'); if (IDs.Length > 0) { VideoFileID = Convert.ToInt32(IDs[0]); OnVideoFileRequested(EventArgs.Empty); } } /// /// Sends the video info. /// /// The ID. /// The title. /// The minutes. /// The seconds. /// The comment. /// The hashvalue. public void SendVideoInfo(int ID, string Title, int Minutes, int Seconds, string Comment, string Hashvalue) { Title = Title.Replace('#', '~'); Comment = Comment.Replace('#', '~'); Hashvalue = Hashvalue.Replace('#', '~'); string strTMP1 = string.Format("{0,2}", Minutes); strTMP1 = strTMP1.Replace(' ', '0'); string strTMP2 = string.Format("{0,2}", Seconds); strTMP2 = strTMP2.Replace(' ', '0'); Send("4005" + ID + "#" + Title + "#" + strTMP1 + ":" + strTMP2 + "#" + Comment + "#" + Hashvalue + "#"); } /// /// Gets the video list. /// /// The received data. private void GetVideoList(byte[] ReceivedData) { string AllIDs = ByteToString(ReceivedData).Substring(4); string[] IDs = AllIDs.Split('#'); if (IDs.Length == 1) { VideoListIDs[0] = 0; VideoListIDs[1] = 0; } else { VideoListIDs[0] = Convert.ToInt32(IDs[0]); VideoListIDs[1] = Convert.ToInt32(IDs[1]); } Message.Enqueue("Video list requested: ID " + VideoListIDs[0] + " to ID " + VideoListIDs[1]); OnStatusMessage(EventArgs.Empty); OnVideoListRequested(EventArgs.Empty); } /// /// Streams the given video-file. /// /// The id. /// The port on with the video is streamed (MUST BE UNUSED). /// The video file to stream. public void StreamVideo(int Id, int Port, string VideoFile) { # region " general variables " if (Multicasting) StopStreaming(); string URL; videoFile = VideoFile.Replace("dshow", ""); string LocalIP = client.Client.LocalEndPoint.ToString(); LocalIP = LocalIP.Remove(LocalIP.LastIndexOf(':')); string RemoteIP = client.Client.RemoteEndPoint.ToString(); RemoteIP = RemoteIP.Remove(RemoteIP.LastIndexOf(':')); vlc.ClearPlaylist(); string[] options = null; # endregion # region " live streaming " if (VideoFile.Contains("dshow")) { bool startMulticast = true; storage = new Storage(true, "NHTMulticast.bin"); if (storage.LoadObject(videoFile) != null) if ((int)storage.LoadObject(videoFile) == 1) { startMulticast = false; } string IP; # region " start Multicasting " if (startMulticast) { storage.SaveObject(videoFile, 1); int ipEnd = (int)storage.LoadObject("MulticastIpEnd"); IP = "224.0.0." + ipEnd.ToString(); storage.SaveObject("MulticastIpEnd", ipEnd + 1); options = new string[] {":sout=#transcode{vcodec=mp4v,vb="+(1024*15)+",scale=1}"+ ":duplicate{dst=std{access=udp,mux=ts,dst=" + IP + ":" + Port + "}}", ":no-one-instance", ":no-loop", ":no-drop-late-frames"}; storage.SaveObject("MulticastingUsers" + videoFile, 0); storage.SaveObject("MulticastingIP" + videoFile, IP); storage.SaveObject("MulticastPort" + videoFile, Port); string target = "dshow://" + " :dshow-vdev=\"" + videoFile + "\"" + " :dshow-adev=\"none\""; vlc.AddTargetAndPlay(target, options); Message.Enqueue("Starting Multicast-Video Stream: " + target + " on Port " + Port); OnStatusMessage(EventArgs.Empty); } # endregion # region " send Multicasting-URL " int multicastUsers = (int)storage.LoadObject("MulticastingUsers" + videoFile) + 1; storage.SaveObject("MulticastingUsers" + videoFile, multicastUsers); Multicasting = true; int port = (int)storage.LoadObject("MulticastPort" + videoFile); string ip = (string)storage.LoadObject("MulticastingIP" + videoFile); URL = @"udp://@" + ip + ":" + port; Message.Enqueue("Adding Multicast User - Users: " + multicastUsers); OnStatusMessage(EventArgs.Empty); # endregion } # endregion else { options = new string[] { ":sout=#standard{access=udp,mux=ts,dst=" + RemoteIP + ":" + Port + "}", ":no-one-instance", ":no-loop", ":no-drop-late-frames" }; URL = @"udp://@:" + Port; VLC.Error err = vlc.AddTargetAndPlay(VideoFile, options); # region " error handling " if((int)err > 0) { if (vlc.IsPlaying) { Message.Enqueue("Starting Video Stream: " + VideoFile + " on Port " + Port); OnStatusMessage(EventArgs.Empty); } else { Message.Enqueue("Error starting to stream " + VideoFile + " on Port " + Port + ": VLC is not playing - " + vlc.GetError()); OnStatusMessage(EventArgs.Empty); } } else if (err == VLC.Error.Success) { err = vlc.Play(); if (err == VLC.Error.Success) { err = vlc.Next(); if (err != VLC.Error.Success) { if (vlc.IsPlaying) { Message.Enqueue("Starting Video Stream: " + VideoFile + " on Port " + Port); OnStatusMessage(EventArgs.Empty); } else { Message.Enqueue("Error starting to stream " + VideoFile + " on Port " + Port + ": VLC is not playing - " + vlc.GetError()); OnStatusMessage(EventArgs.Empty); } } else { Message.Enqueue("Error selecting the target " + VideoFile + " on Port " + Port + ": " + vlc.GetError()); OnStatusMessage(EventArgs.Empty); } } else { Message.Enqueue("Error playing the stream " + VideoFile + " on Port " + Port + ": " + vlc.GetError()); OnStatusMessage(EventArgs.Empty); } } else { Message.Enqueue("Error adding target " + VideoFile + " on Port " + Port + ": " + err.ToString() + " - " + vlc.GetError()); OnStatusMessage(EventArgs.Empty); } # endregion } Send("4015" + Id + "#" + URL + "#"); } /// /// Stops the streaming. /// public void StopStreaming() { int multicastingUsers = 0; if (Multicasting) { storage = new Storage(true, "NHTMulticast.bin"); multicastingUsers = (int)storage.LoadObject("MulticastingUsers" + videoFile); multicastingUsers--; storage.SaveObject("MulticastingUsers" + videoFile, multicastingUsers); Message.Enqueue("Removed Multicast User - Users: " + multicastingUsers); OnStatusMessage(EventArgs.Empty); } if (vlc.IsPlaying) { if (Multicasting && multicastingUsers == 0) { storage.SaveObject(videoFile, 0); storage.SaveObject(videoFile, null); storage.SaveObject("MulticastingUsers" + videoFile, 0); vlc.Stop(); Message.Enqueue("Stopped Multicast streaming"); OnStatusMessage(EventArgs.Empty); } else { vlc.Stop(); Message.Enqueue("Stopped Streaming"); OnStatusMessage(EventArgs.Empty); } } Multicasting = false; } /// /// Seeks the stream to the given position. /// /// The posistion in seconds. public bool SeekStream(int PosInSeconds) { if (vlc.IsPlaying) { if (vlc.GetLengthSecs() > PosInSeconds) { vlc.SetPositionSecs(PosInSeconds); return true; } } return false; } } }