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;
}
}
}