├── .gitattributes ├── .gitignore ├── README.md ├── SharpStreaming.Core ├── ClassDiagram1.cd ├── Client │ ├── FilePermission.cs │ ├── FileSink.cs │ ├── MediaSession.cs │ ├── RtpSource.cs │ ├── RtspClient.cs │ └── TFilePermissionEventArgs.cs ├── Common │ ├── ClientSocketBase.cs │ ├── ClientSocketTcp.cs │ ├── ClientSocketUdp.cs │ ├── Config.cs │ ├── Constants.cs │ ├── Enums.cs │ ├── Log.cs │ ├── RtpPacket.cs │ ├── RtpUtils.cs │ ├── RtspCommon.cs │ ├── TExceptionEventArgs.cs │ ├── TSocketEventArgs.cs │ └── Utils.cs ├── Lib │ └── Microsoft.DirectX.AudioVideoPlayback.dll ├── Properties │ └── AssemblyInfo.cs ├── Server │ ├── ClientSession.cs │ ├── ClientSessionInfo.cs │ ├── MPEG2TransportFileServerMediaSession.cs │ ├── MPEG2TransportStreamFileSource.cs │ ├── MediaSource.cs │ ├── RtpSink.cs │ ├── RtspServer.cs │ ├── ServerMediaSession.cs │ ├── SocketListener.cs │ ├── StreamState.cs │ └── TClientSessionEventArgs.cs ├── Settings.StyleCop └── SharpStreaming.Core.csproj ├── SharpStreaming.sln ├── SharpStreamingClient ├── AboutForm.cs ├── AboutForm.designer.cs ├── AboutForm.resx ├── ClientForm.cs ├── ClientForm.designer.cs ├── ClientForm.resx ├── ColorSlider.cs ├── ColorSlider.designer.cs ├── ColorSlider.resx ├── OpenForm.Designer.cs ├── OpenForm.cs ├── OpenForm.resx ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── SharpStreamingClient.csproj ├── client.ico ├── res │ └── Images │ │ ├── about_top.png │ │ ├── bg.png │ │ ├── player.png │ │ ├── statusbar_bg.png │ │ ├── toolbar_about.png │ │ ├── toolbar_bg.png │ │ ├── toolbar_open.png │ │ ├── toolbar_pause.png │ │ ├── toolbar_play.png │ │ └── toolbar_stop.png └── src │ └── Program.cs └── SharpStreamingServer ├── AboutForm.cs ├── AboutForm.designer.cs ├── AboutForm.resx ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── ServerForm.cs ├── ServerForm.designer.cs ├── ServerForm.resx ├── SettingsForm.cs ├── SettingsForm.designer.cs ├── SettingsForm.resx ├── SharpStreamingServer.csproj ├── res ├── Images │ ├── about_top.png │ ├── bg.png │ ├── settings_normal.png │ ├── settings_selected.png │ ├── statusbar_bg.png │ ├── toolbar_about.png │ ├── toolbar_bg.png │ ├── toolbar_hide.png │ ├── toolbar_quit.png │ ├── toolbar_setting.png │ ├── toolbar_start.png │ └── toolbar_stop.png └── Options │ ├── BaseControl.cs │ ├── BaseControl.designer.cs │ ├── BaseControl.resx │ ├── CatalogControl.cs │ ├── CatalogControl.designer.cs │ ├── CatalogControl.resx │ ├── GeneralControl.cs │ ├── GeneralControl.designer.cs │ └── GeneralControl.resx ├── src ├── OptionsTreeNode.cs └── Program.cs └── web_server.ico /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SharpStreaming 2 | ============== 3 | 4 | RTSP Server and Client. 5 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Client/FilePermission.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Simon.SharpStreaming.Core 7 | { 8 | public class FilePermission 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Client/FileSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | 6 | namespace Simon.SharpStreaming.Core 7 | { 8 | public class FileSink 9 | { 10 | #region Private Member Fields 11 | /// 12 | /// A lock of the file operation. 13 | /// 14 | private static object mutex = new object(); 15 | 16 | /// 17 | /// The object of the FileStream. 18 | /// 19 | private FileStream fileStream; 20 | 21 | private string filePath; 22 | private long fileSize; 23 | #endregion 24 | 25 | #region Public Events 26 | public event EventHandler UpdateAccessRange; 27 | #endregion 28 | 29 | #region Class Constructor 30 | /// 31 | /// Initializes a new instance of the class. 32 | /// 33 | /// The file path. 34 | /// Size of the file. 35 | public FileSink(string filePath, long fileSize) 36 | { 37 | this.filePath = filePath; 38 | this.fileSize = fileSize; 39 | 40 | InitFileStream(); 41 | } 42 | #endregion 43 | 44 | #region Public Methods 45 | /// 46 | /// Writes the data to the file. 47 | /// 48 | /// The frame buffer. 49 | /// Size of the frame. 50 | /// The position. 51 | public void WriteDataToFile(byte[] frameBuffer, int frameSize, long position) 52 | { 53 | lock (mutex) 54 | { 55 | try 56 | { 57 | if (fileStream != null && fileStream.CanSeek) 58 | { 59 | fileStream.Seek(position, SeekOrigin.Begin); 60 | } 61 | 62 | if (fileStream != null && fileStream.CanWrite) 63 | { 64 | fileStream.Write(frameBuffer, 0, frameSize); 65 | fileStream.Flush(); 66 | } 67 | } 68 | catch (System.Exception e) 69 | { 70 | Utils.OutputMessage(false, MsgLevel.Error, "FileSink -- WriteDataToFile", e.Message); 71 | } 72 | } 73 | } 74 | 75 | /// 76 | /// Closes the file stream. 77 | /// 78 | public void CloseFileStream() 79 | { 80 | if (fileStream != null) 81 | { 82 | fileStream.Close(); 83 | fileStream = null; 84 | } 85 | } 86 | #endregion 87 | 88 | #region Private Methods 89 | /// 90 | /// Initializes the file stream object. 91 | /// 92 | private void InitFileStream() 93 | { 94 | lock (mutex) 95 | { 96 | try 97 | { 98 | fileStream = new FileStream(filePath, FileMode.Create, 99 | FileAccess.ReadWrite, FileShare.ReadWrite); 100 | //fileStream.SetLength(fileSize); 101 | } 102 | catch (System.Exception e) 103 | { 104 | Utils.OutputMessage(false, MsgLevel.Error, "FileSink -- InitFileStream", e.Message); 105 | } 106 | } 107 | } 108 | #endregion 109 | 110 | #region Protected Virtual Methods 111 | /// 112 | /// Called when [update access range]. 113 | /// 114 | /// The begin. 115 | /// The end. 116 | protected virtual void OnUpdateAccessRange(long begin, long end) 117 | { 118 | EventHandler handler = this.UpdateAccessRange; 119 | if (handler != null) 120 | { 121 | TFilePermissionEventArgs e = new TFilePermissionEventArgs(begin, end); 122 | handler(this, e); 123 | } 124 | } 125 | #endregion 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Client/MediaSession.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Net.Sockets; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace Simon.SharpStreaming.Core 6 | { 7 | public class MediaSession 8 | { 9 | private string sdpDescription; 10 | 11 | #region Public Properties 12 | /// 13 | /// Gets or sets the RTP source. 14 | /// 15 | /// The RTP source. 16 | public RtpSource Source { get; set; } 17 | 18 | /// 19 | /// Gets or sets the size of the file. 20 | /// 21 | /// The size of the file. 22 | public long FileSize { get; protected set; } 23 | 24 | /// 25 | /// Gets or sets the play start time. 26 | /// 27 | /// The play start time. 28 | public double PlayStartTime { get; protected set; } 29 | 30 | /// 31 | /// Gets or sets the play end time. 32 | /// 33 | /// The play end time. 34 | public double PlayEndTime { get; protected set; } 35 | #endregion 36 | 37 | #region Class Constructor 38 | /// 39 | /// Initializes a new instance of the class. 40 | /// 41 | /// The SDP description. 42 | public MediaSession(string sdpDescription) 43 | { 44 | this.sdpDescription = sdpDescription; 45 | } 46 | #endregion 47 | 48 | /// 49 | /// Resolves the SDP description. 50 | /// 51 | /// Success or failed. 52 | public bool ResolveSdpDescription() 53 | { 54 | if (string.IsNullOrEmpty(sdpDescription)) 55 | { 56 | return false; 57 | } 58 | 59 | // Splits the SDP description string to multiline: 60 | string[] sdpArray = Regex.Split(sdpDescription, @"[\r\n]+"); 61 | 62 | bool result = ParseSdpRangeAttribute(sdpArray); 63 | if (!result) 64 | { 65 | return false; 66 | } 67 | 68 | result = ParseSdpSizeAttribute(sdpArray); 69 | if (!result) 70 | { 71 | return false; 72 | } 73 | 74 | result = ParseSdpControlAttribute(sdpArray); 75 | if (!result) 76 | { 77 | return false; 78 | } 79 | 80 | return true; 81 | } 82 | 83 | /// 84 | /// Creates the RTP source. 85 | /// 86 | /// The file sink. 87 | /// The server address. 88 | /// The server RTP port. 89 | /// The server RTCP port. 90 | /// The client RTP port. 91 | /// The client RTCP port. 92 | /// Succeeded or failed. 93 | public bool CreateRtpSource(FileSink fileSink, string serverAddress, 94 | int serverRtpPort, int serverRtcpPort, 95 | int clientRtpPort, int clientRtcpPort) 96 | { 97 | // Creates rtp socket and rtcp socket: 98 | ClientSocketBase clientRtpSocket = null; 99 | ClientSocketBase clientRtcpSocket = null; 100 | Socket socket = null; 101 | socket = Utils.CreateUdpSocket(clientRtpPort); 102 | if (socket == null) 103 | { 104 | return false; 105 | } 106 | 107 | IPEndPoint iep = new IPEndPoint(IPAddress.Parse(serverAddress), serverRtpPort); 108 | clientRtpSocket = new ClientSocketUdp(socket, (EndPoint)iep); 109 | 110 | socket = Utils.CreateUdpSocket(clientRtcpPort); 111 | if (socket != null) 112 | { 113 | iep = new IPEndPoint(IPAddress.Parse(serverAddress), serverRtcpPort); 114 | clientRtcpSocket = new ClientSocketUdp(socket, (EndPoint)iep); 115 | } 116 | 117 | Source = new RtpSource(fileSink, clientRtpSocket); 118 | if (Source == null) 119 | { 120 | return false; 121 | } 122 | 123 | return true; 124 | } 125 | 126 | /// 127 | /// Parses the SDP range attribute. 128 | /// 129 | /// The SDP array. 130 | /// Succeeded or failed. 131 | private bool ParseSdpRangeAttribute(string[] sdpArray) 132 | { 133 | string temp = string.Empty; 134 | 135 | foreach (string s in sdpArray) 136 | { 137 | if (s.Contains("a=range:npt=")) 138 | { 139 | temp = s; 140 | break; 141 | } 142 | } 143 | 144 | if (string.IsNullOrEmpty(temp)) 145 | { 146 | return false; 147 | } 148 | 149 | temp = temp.Substring(("a=range:npt=").Length); 150 | 151 | string rangeStartStr = string.Empty; 152 | string rangeEndStr = string.Empty; 153 | string[] rangeArray = Regex.Split(temp, "-"); 154 | if (rangeArray.Length < 2) 155 | { 156 | return false; 157 | } 158 | else if (rangeArray.Length == 2) 159 | { 160 | rangeStartStr = rangeArray[0].Trim(); 161 | rangeEndStr = rangeArray[1].Trim(); 162 | } 163 | 164 | PlayStartTime = Utils.StringToDouble(rangeStartStr); 165 | PlayEndTime = Utils.StringToDouble(rangeEndStr); 166 | 167 | return true; 168 | } 169 | 170 | /// 171 | /// Parses the SDP size attribute. 172 | /// 173 | /// The SDP array. 174 | /// Succeeded or failed. 175 | private bool ParseSdpSizeAttribute(string[] sdpArray) 176 | { 177 | string temp = string.Empty; 178 | 179 | foreach (string s in sdpArray) 180 | { 181 | if (s.Contains("a=size:fs=")) 182 | { 183 | temp = s; 184 | break; 185 | } 186 | } 187 | 188 | if (string.IsNullOrEmpty(temp)) 189 | { 190 | return false; 191 | } 192 | 193 | string fileSize = temp.Substring(("a=size:fs=").Length).Trim(); 194 | 195 | FileSize = Utils.StringToLong(fileSize); 196 | 197 | return true; 198 | } 199 | 200 | /// 201 | /// Parses the SDP control attribute. 202 | /// 203 | /// The SDP array. 204 | /// Succeeded or failed. 205 | private bool ParseSdpControlAttribute(string[] sdpArray) 206 | { 207 | string temp = string.Empty; 208 | 209 | foreach (string s in sdpArray) 210 | { 211 | if (s.Contains("a=control:")) 212 | { 213 | temp = s; 214 | break; 215 | } 216 | } 217 | 218 | if (string.IsNullOrEmpty(temp)) 219 | { 220 | return false; 221 | } 222 | 223 | string trackId = temp.Substring(("a=control:").Length).Trim(); 224 | 225 | return true; 226 | } 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Client/RtpSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Simon.SharpStreaming.Core 4 | { 5 | public class RtpSource 6 | { 7 | #region Private Member Fields 8 | private FileSink fileSink; 9 | private ClientSocketBase clientRtpSocket; 10 | private RtpPacket rtpPacket; 11 | 12 | private int preferredFrameSize; 13 | private int internalPacketSize; 14 | #endregion 15 | 16 | #region Class Constructor 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// The file sink. 21 | /// The client RTP socket. 22 | public RtpSource(FileSink fileSink, ClientSocketBase clientRtpSocket) 23 | { 24 | this.fileSink = fileSink; 25 | this.clientRtpSocket = clientRtpSocket; 26 | 27 | this.clientRtpSocket.DatagramReceived += new EventHandler(this.OnDatagramReceived); 28 | 29 | rtpPacket = new RtpPacket(); 30 | 31 | preferredFrameSize = 1024; 32 | internalPacketSize = preferredFrameSize + 16; 33 | } 34 | #endregion 35 | 36 | #region Public Methods 37 | /// 38 | /// Starts the playing. 39 | /// 40 | public void StartPlaying() 41 | { 42 | if (clientRtpSocket != null) 43 | { 44 | clientRtpSocket.ReceiveDatagram(); 45 | } 46 | } 47 | 48 | /// 49 | /// Closes the file sink. 50 | /// 51 | public void CloseFileSink() 52 | { 53 | if (fileSink != null) 54 | { 55 | fileSink.CloseFileStream(); 56 | } 57 | } 58 | #endregion 59 | 60 | #region Private Methods 61 | /// 62 | /// Handles the incoming packet. 63 | /// 64 | /// The packet buffer. 65 | /// Size of the packet. 66 | private void HandleIncomingPacket(byte[] packetBuffer, int packetSize) 67 | { 68 | long position = 0; 69 | int frameSize = 0; 70 | byte[] frameBuffer = new byte[preferredFrameSize]; 71 | 72 | int dataSize = 0; 73 | byte[] dataBuffer = new byte[internalPacketSize]; 74 | 75 | // First, Parses the RTP packet: 76 | if (rtpPacket != null) 77 | { 78 | rtpPacket.ParseRtpPacket(packetBuffer, packetSize, ref dataBuffer, ref dataSize); 79 | } 80 | 81 | // Then, Parses the internal packet: 82 | /* The internal packet has the following format: 83 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 84 | * [positionLength][position][dataLengthLength][dataLength][data...] 85 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 86 | */ 87 | try 88 | { 89 | // Gets and converts the position length 90 | int positionLength = (int)dataBuffer[0]; 91 | 92 | // Gets and converts the position 93 | byte[] bytesPosition = new byte[positionLength]; 94 | Array.Copy(dataBuffer, 1, bytesPosition, 0, positionLength); 95 | position = Utils.BytesToLong(bytesPosition); 96 | 97 | // Gets and converts the frame size length 98 | int frameSizeLength = (int)dataBuffer[1 + positionLength]; 99 | 100 | // Gets and converts the frame size 101 | byte[] bytesFrameSize = new byte[frameSizeLength]; 102 | Array.Copy(dataBuffer, 1 + positionLength + 1, bytesFrameSize, 0, frameSizeLength); 103 | frameSize = Utils.BytesToInteger(bytesFrameSize); 104 | 105 | // Gets the frame buffer 106 | Array.Copy(dataBuffer, 1 + positionLength + 1 + frameSizeLength, frameBuffer, 0, frameSize); 107 | } 108 | catch (System.Exception e) 109 | { 110 | Utils.OutputMessage(false, MsgLevel.Error, "RtpSource -- HandleIncomingPacket", e.Message); 111 | } 112 | 113 | // Finally, adds the frame to the file: 114 | if (fileSink != null) 115 | { 116 | fileSink.WriteDataToFile(frameBuffer, frameSize, position); 117 | } 118 | } 119 | #endregion 120 | 121 | #region Protected Virtual Methods 122 | /// 123 | /// Called when [datagram received]. 124 | /// 125 | /// The sender. 126 | /// The instance containing the event data. 127 | protected virtual void OnDatagramReceived(object sender, TSocketEventArgs e) 128 | { 129 | HandleIncomingPacket(e.RecvBuffer, e.RecvBufferSize); 130 | } 131 | #endregion 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Client/TFilePermissionEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Simon.SharpStreaming.Core 7 | { 8 | public class TFilePermissionEventArgs : EventArgs 9 | { 10 | /// 11 | /// The begin offset. 12 | /// 13 | public readonly long BeginOffset; 14 | 15 | /// 16 | /// The end offset. 17 | /// 18 | public readonly long EndOffset; 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// The begin. 24 | /// The end. 25 | public TFilePermissionEventArgs(long begin, long end) 26 | { 27 | this.BeginOffset = begin; 28 | this.EndOffset = end; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/ClientSocketBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Simon.SharpStreaming.Core 4 | { 5 | /// 6 | /// A base class for client socket. 7 | /// 8 | public class ClientSocketBase 9 | { 10 | #region Public Class Events 11 | public event EventHandler ClientTeardown; 12 | public event EventHandler DatagramReceived; 13 | public event EventHandler ExceptionOccurred; 14 | #endregion 15 | 16 | #region Public Virtual Methods 17 | /// 18 | /// Sends the datagram with the asynchronous mode. 19 | /// 20 | /// The send buffer. 21 | /// Size of the send buffer. 22 | public virtual void SendDatagram(byte[] sendBuffer, int sendBufferSize) 23 | { 24 | // No implementation. 25 | } 26 | 27 | /// 28 | /// Receives the datagram with the asynchronous mode. 29 | /// 30 | public virtual void ReceiveDatagram() 31 | { 32 | // No implementation. 33 | } 34 | 35 | /// 36 | /// Closes the client socket. 37 | /// 38 | public virtual void CloseClientSocket() 39 | { 40 | // No implementation. 41 | } 42 | #endregion 43 | 44 | #region Protected Virtual Methods 45 | /// 46 | /// Ends to send the datagram. 47 | /// 48 | /// The iar. 49 | protected virtual void EndSendDatagram(IAsyncResult iar) 50 | { 51 | // No implementation. 52 | } 53 | 54 | /// 55 | /// Ends to receive the datagram. 56 | /// 57 | /// The iar. 58 | protected virtual void EndReceiveDatagram(IAsyncResult iar) 59 | { 60 | // No implementation. 61 | } 62 | 63 | /// 64 | /// Called when [client tear down]. 65 | /// 66 | protected virtual void OnClientTeardown() 67 | { 68 | EventHandler handler = this.ClientTeardown; 69 | if (handler != null) 70 | { 71 | handler(this, EventArgs.Empty); 72 | } 73 | } 74 | 75 | /// 76 | /// Called when [datagram received]. 77 | /// 78 | /// The received buffer. 79 | /// Size of the received buffer. 80 | protected virtual void OnDatagramReceived(byte[] recvBuffer, int recvBufferSize) 81 | { 82 | EventHandler handler = this.DatagramReceived; 83 | if (handler != null) 84 | { 85 | TSocketEventArgs e = new TSocketEventArgs(recvBuffer, recvBufferSize); 86 | handler(this, e); 87 | } 88 | } 89 | 90 | /// 91 | /// Called when [exception occurred]. 92 | /// 93 | /// The ex. 94 | protected virtual void OnExceptionOccurred(Exception ex) 95 | { 96 | EventHandler handler = this.ExceptionOccurred; 97 | if (handler != null) 98 | { 99 | TExceptionEventArgs e = new TExceptionEventArgs(ex); 100 | handler(this, e); 101 | } 102 | } 103 | #endregion 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/ClientSocketTcp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Sockets; 3 | 4 | namespace Simon.SharpStreaming.Core 5 | { 6 | public class ClientSocketTcp : ClientSocketBase 7 | { 8 | #region Private Member Fields 9 | /// 10 | /// A lock of send datagram or receive datagram. 11 | /// 12 | private static object mutex = new object(); 13 | 14 | /// 15 | /// The client socket. 16 | /// 17 | private Socket socket; 18 | 19 | /// 20 | /// The received buffer. 21 | /// 22 | private byte[] recvBuffer; 23 | 24 | /// 25 | /// The received buffer size. 26 | /// 27 | private int recvBufferSize; 28 | #endregion 29 | 30 | #region Class Constructor 31 | /// 32 | /// Initializes a new instance of the class. 33 | /// 34 | /// The socket. 35 | public ClientSocketTcp(Socket socket) 36 | { 37 | this.socket = socket; 38 | 39 | this.recvBufferSize = 1024 * 4; // 4 KB buffer 40 | this.recvBuffer = new byte[recvBufferSize]; 41 | } 42 | #endregion 43 | 44 | #region Public Override Methods 45 | /// 46 | /// Sends the datagram with the asynchronous mode. 47 | /// 48 | /// The send buffer. 49 | /// Size of the send buffer. 50 | public override void SendDatagram(byte[] sendBuffer, int sendBufferSize) 51 | { 52 | lock (mutex) 53 | { 54 | try 55 | { 56 | int bufferOffset = 0; 57 | 58 | // Sends data asynchronously to a connected socket. 59 | if (socket != null && socket.Connected) 60 | { 61 | socket.BeginSend(sendBuffer, bufferOffset, sendBufferSize, SocketFlags.None, this.EndSendDatagram, this); 62 | } 63 | } 64 | catch (System.Exception e) 65 | { 66 | this.OnClientTeardown(); 67 | this.OnExceptionOccurred(e); 68 | Utils.OutputMessage(false, MsgLevel.Error, "ClientSocketTcp -- SendDatagram", e.Message); 69 | } 70 | } 71 | } 72 | 73 | /// 74 | /// Receives the datagram from the client with asynchronous mode. 75 | /// 76 | public override void ReceiveDatagram() 77 | { 78 | lock (mutex) 79 | { 80 | try 81 | { 82 | int bufferOffset = 0; 83 | 84 | // Begins to asynchronously receive data from a connected socket. 85 | if (socket != null && socket.Connected) 86 | { 87 | socket.BeginReceive(recvBuffer, bufferOffset, recvBufferSize, SocketFlags.None, this.EndReceiveDatagram, this); 88 | } 89 | } 90 | catch (System.Exception e) 91 | { 92 | this.OnClientTeardown(); 93 | this.OnExceptionOccurred(e); 94 | Utils.OutputMessage(false, MsgLevel.Error, "ClientSocketTcp -- ReceiveDatagram", e.Message); 95 | } 96 | } 97 | } 98 | 99 | /// 100 | /// Closes the client socket. 101 | /// 102 | public override void CloseClientSocket() 103 | { 104 | try 105 | { 106 | if (socket != null) 107 | { 108 | // Disables sends and receives on a socket. 109 | socket.Shutdown(SocketShutdown.Both); 110 | 111 | // Closes the socket connection and releases all associated resources. 112 | socket.Close(); 113 | } 114 | } 115 | catch 116 | { 117 | // Shut down it by force, ignores any exceptions. 118 | } 119 | } 120 | #endregion 121 | 122 | #region Protected Override Methods 123 | /// 124 | /// Ends to send the datagram. 125 | /// 126 | /// The iar. 127 | protected override void EndSendDatagram(IAsyncResult iar) 128 | { 129 | lock (mutex) 130 | { 131 | try 132 | { 133 | if (socket != null && socket.Connected) 134 | { 135 | // Ends a pending asynchronous send. 136 | socket.EndSend(iar); 137 | iar.AsyncWaitHandle.Close(); 138 | } 139 | else 140 | { 141 | this.OnClientTeardown(); 142 | } 143 | } 144 | catch (System.Exception e) 145 | { 146 | this.OnClientTeardown(); 147 | this.OnExceptionOccurred(e); 148 | Utils.OutputMessage(false, MsgLevel.Error, "ClientSocketTcp -- EndSendDatagram", e.Message); 149 | } 150 | } 151 | } 152 | 153 | /// 154 | /// Ends to receive the datagram. 155 | /// 156 | /// The iar. 157 | protected override void EndReceiveDatagram(IAsyncResult iar) 158 | { 159 | lock (mutex) 160 | { 161 | try 162 | { 163 | if (socket != null && socket.Connected) 164 | { 165 | // Ends a pending asynchronous read. 166 | int readBufferSize = socket.EndReceive(iar); 167 | iar.AsyncWaitHandle.Close(); 168 | 169 | if (readBufferSize == 0) 170 | { 171 | this.OnClientTeardown(); 172 | } 173 | else 174 | { 175 | // Reports the received datagram to the client session. 176 | this.OnDatagramReceived(recvBuffer, readBufferSize); 177 | 178 | // Continues to receive the datagram from the client. 179 | ReceiveDatagram(); 180 | } 181 | } 182 | else 183 | { 184 | this.OnClientTeardown(); 185 | } 186 | } 187 | catch (System.Exception e) 188 | { 189 | this.OnClientTeardown(); 190 | this.OnExceptionOccurred(e); 191 | Utils.OutputMessage(false, MsgLevel.Error, "ClientSocketTcp -- EndReceiveDatagram", e.Message); 192 | } 193 | } 194 | } 195 | 196 | /// 197 | /// Called when [client tear down]. 198 | /// 199 | protected override void OnClientTeardown() 200 | { 201 | // Calls the base class event invocation method. 202 | base.OnClientTeardown(); 203 | } 204 | 205 | /// 206 | /// Called when [datagram received]. 207 | /// 208 | /// The received buffer. 209 | /// Size of the received buffer. 210 | protected override void OnDatagramReceived(byte[] recvBuffer, int recvBufferSize) 211 | { 212 | // Calls the base class event invocation method. 213 | base.OnDatagramReceived(recvBuffer, recvBufferSize); 214 | } 215 | 216 | /// 217 | /// Called when [exception occurred]. 218 | /// 219 | /// The ex. 220 | protected override void OnExceptionOccurred(Exception ex) 221 | { 222 | // Calls the base class event invocation method. 223 | base.OnExceptionOccurred(ex); 224 | } 225 | #endregion 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/ClientSocketUdp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | 5 | namespace Simon.SharpStreaming.Core 6 | { 7 | public class ClientSocketUdp : ClientSocketBase 8 | { 9 | #region Private Member Fields 10 | /// 11 | /// A lock of send datagram or receive datagram. 12 | /// 13 | private static object mutex = new object(); 14 | 15 | /// 16 | /// The client socket. 17 | /// 18 | private Socket socket; 19 | 20 | /// 21 | /// The remote end point. 22 | /// 23 | private EndPoint remoteEndPoint; 24 | 25 | /// 26 | /// The received buffer. 27 | /// 28 | private byte[] recvBuffer; 29 | 30 | /// 31 | /// The received buffer size. 32 | /// 33 | private int recvBufferSize; 34 | #endregion 35 | 36 | #region Class Constructor 37 | /// 38 | /// Initializes a new instance of the class. 39 | /// 40 | /// The socket. 41 | /// The remote end point. 42 | public ClientSocketUdp(Socket socket, EndPoint remoteEndPoint) 43 | { 44 | this.socket = socket; 45 | this.remoteEndPoint = remoteEndPoint; 46 | 47 | this.recvBufferSize = 1024 * 4; // 4 KB buffer 48 | this.recvBuffer = new byte[recvBufferSize]; 49 | } 50 | #endregion 51 | 52 | #region Public Override Methods 53 | /// 54 | /// Sends the datagram with the asynchronous mode. 55 | /// 56 | /// The send buffer. 57 | /// Size of the send buffer. 58 | public override void SendDatagram(byte[] sendBuffer, int sendBufferSize) 59 | { 60 | lock (mutex) 61 | { 62 | try 63 | { 64 | int bufferOffset = 0; 65 | 66 | // Sends data asynchronously to a socket. 67 | if (socket != null) 68 | { 69 | socket.BeginSendTo(sendBuffer, bufferOffset, sendBufferSize, SocketFlags.None, this.remoteEndPoint, this.EndSendDatagram, this); 70 | } 71 | } 72 | catch (System.Exception e) 73 | { 74 | this.OnClientTeardown(); 75 | this.OnExceptionOccurred(e); 76 | Utils.OutputMessage(false, MsgLevel.Error, "ClientSocketUdp -- SendDatagram", e.Message); 77 | } 78 | } 79 | } 80 | 81 | /// 82 | /// Receives the datagram with the asynchronous mode. 83 | /// 84 | public override void ReceiveDatagram() 85 | { 86 | lock (mutex) 87 | { 88 | try 89 | { 90 | int bufferOffset = 0; 91 | 92 | // Begins to asynchronously receive data from a socket. 93 | if (socket != null) 94 | { 95 | socket.BeginReceiveFrom(recvBuffer, bufferOffset, recvBufferSize, SocketFlags.None, ref this.remoteEndPoint, this.EndReceiveDatagram, this); 96 | } 97 | } 98 | catch (System.Exception e) 99 | { 100 | this.OnClientTeardown(); 101 | this.OnExceptionOccurred(e); 102 | Utils.OutputMessage(false, MsgLevel.Error, "ClientSocketUdp -- ReceiveDatagram", e.Message); 103 | } 104 | } 105 | } 106 | 107 | /// 108 | /// Closes the client socket. 109 | /// 110 | public override void CloseClientSocket() 111 | { 112 | try 113 | { 114 | if (socket != null) 115 | { 116 | // Disables sends and receives on a Socket. 117 | socket.Shutdown(SocketShutdown.Both); 118 | 119 | // Closes the socket and releases all associated resources. 120 | socket.Close(); 121 | } 122 | } 123 | catch 124 | { 125 | // Shut down it by force, ignores any exceptions. 126 | } 127 | } 128 | #endregion 129 | 130 | #region Protected Override Methods 131 | /// 132 | /// Ends to send the datagram. 133 | /// 134 | /// The iar. 135 | protected override void EndSendDatagram(IAsyncResult iar) 136 | { 137 | lock (mutex) 138 | { 139 | try 140 | { 141 | if (socket != null) 142 | { 143 | // Ends a pending asynchronous send. 144 | socket.EndSendTo(iar); 145 | iar.AsyncWaitHandle.Close(); 146 | } 147 | } 148 | catch (System.Exception e) 149 | { 150 | this.OnClientTeardown(); 151 | this.OnExceptionOccurred(e); 152 | Utils.OutputMessage(false, MsgLevel.Error, "ClientSocketUdp -- EndSendDatagram", e.Message); 153 | } 154 | } 155 | } 156 | 157 | /// 158 | /// Ends to receive the datagram. 159 | /// 160 | /// The iar. 161 | protected override void EndReceiveDatagram(IAsyncResult iar) 162 | { 163 | lock (mutex) 164 | { 165 | try 166 | { 167 | if (socket != null) 168 | { 169 | // Ends a pending asynchronous read. 170 | int readBufferSize = socket.EndReceiveFrom(iar, ref remoteEndPoint); 171 | iar.AsyncWaitHandle.Close(); 172 | 173 | if (readBufferSize == 0) 174 | { 175 | // Can not receive data, is it an error? 176 | } 177 | else 178 | { 179 | // Reports the received datagram to the client session. 180 | this.OnDatagramReceived(recvBuffer, readBufferSize); 181 | 182 | // Continues to receive the datagram from the client. 183 | ReceiveDatagram(); 184 | } 185 | } 186 | } 187 | catch (System.Exception e) 188 | { 189 | this.OnClientTeardown(); 190 | this.OnExceptionOccurred(e); 191 | Utils.OutputMessage(false, MsgLevel.Error, "ClientSocketUdp -- EndReceiveDatagram", e.Message); 192 | } 193 | } 194 | } 195 | 196 | /// 197 | /// Called when [client tear down]. 198 | /// 199 | protected override void OnClientTeardown() 200 | { 201 | // Calls the base class event invocation method. 202 | base.OnClientTeardown(); 203 | } 204 | 205 | /// 206 | /// Called when [datagram received]. 207 | /// 208 | /// The received buffer. 209 | /// Size of the received buffer. 210 | protected override void OnDatagramReceived(byte[] recvBuffer, int recvBufferSize) 211 | { 212 | // Calls the base class event invocation method. 213 | base.OnDatagramReceived(recvBuffer, recvBufferSize); 214 | } 215 | 216 | /// 217 | /// Called when [exception occurred]. 218 | /// 219 | /// The ex. 220 | protected override void OnExceptionOccurred(Exception ex) 221 | { 222 | // Calls the base class event invocation method. 223 | base.OnExceptionOccurred(ex); 224 | } 225 | #endregion 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/Config.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Runtime.InteropServices; 3 | using System.Text; 4 | 5 | namespace Simon.SharpStreaming.Core 6 | { 7 | /// 8 | /// A config class that includes the operations of reading and/or 9 | /// writing from/to the config file of ini. And also, it includes 10 | /// loading the default config values. 11 | /// 12 | public class Config 13 | { 14 | #region Dll Import Declare 15 | /// 16 | /// Writes the private profile string. 17 | /// 18 | /// The section. 19 | /// The key. 20 | /// The value. 21 | /// The file path. 22 | /// The number of characters to be written. 23 | [DllImport("kernel32")] 24 | private static extern long WritePrivateProfileString( 25 | string section, string key, string value, string filePath); 26 | 27 | /// 28 | /// Gets the private profile string. 29 | /// 30 | /// The section. 31 | /// The key. 32 | /// The def. 33 | /// The value. 34 | /// The size. 35 | /// The file path. 36 | /// The number of characters copied to the buffer, not including the terminating null character. 37 | [DllImport("kernel32")] 38 | private static extern int GetPrivateProfileString( 39 | string section, string key, string def, StringBuilder value, int size, string filePath); 40 | #endregion 41 | 42 | #region Private Member Fields 43 | /// 44 | /// A table of the default config values. 45 | /// 46 | private Dictionary defaultConfigValueTable; 47 | 48 | /// 49 | /// The path of the config file. 50 | /// 51 | private string configFilePath; 52 | #endregion 53 | 54 | #region Class Constructor 55 | /// 56 | /// Initializes a new instance of the class. 57 | /// 58 | public Config() 59 | { 60 | defaultConfigValueTable = new Dictionary(); 61 | 62 | configFilePath = System.Environment.CurrentDirectory + Constants.CONFIG_FILE_NAME; 63 | 64 | this.LoadDefaultConfigValue(); 65 | } 66 | #endregion 67 | 68 | #region Public Methods 69 | /// 70 | /// Gets the config value. 71 | /// 72 | /// The section. 73 | /// The key. 74 | /// The value. 75 | public string GetConfigValue(string section, string key) 76 | { 77 | string value = string.Empty; 78 | 79 | value = ReadFromIniFile(section, key); 80 | if (string.IsNullOrEmpty(value)) 81 | { 82 | value = GetDefaultConfigValue(key); 83 | } 84 | 85 | return value; 86 | } 87 | 88 | /// 89 | /// Sets the config value. 90 | /// 91 | /// The type. 92 | /// The section. 93 | /// The key. 94 | /// The value. 95 | public void SetConfigValue(string section, string key, T value) 96 | { 97 | WriteToIniFile(section, key, value.ToString()); 98 | } 99 | #endregion 100 | 101 | #region Private Methods 102 | /// 103 | /// Loads the default config value. 104 | /// 105 | private void LoadDefaultConfigValue() 106 | { 107 | defaultConfigValueTable.Add(Constants.CONFIG_KEY_MAXCONNECTIONCOUNT, "500"); 108 | defaultConfigValueTable.Add(Constants.CONFIG_KEY_MAXSESSIONTIMEOUT, "60000"); 109 | defaultConfigValueTable.Add(Constants.CONFIG_KEY_SERVERPORT, "8554"); 110 | defaultConfigValueTable.Add(Constants.CONFIG_KEY_FILECATALOG, "d:\\"); 111 | } 112 | 113 | /// 114 | /// Gets the default config value. 115 | /// 116 | /// The key. 117 | /// The default value. 118 | private string GetDefaultConfigValue(string key) 119 | { 120 | string defaultValue = string.Empty; 121 | 122 | lock (defaultConfigValueTable) 123 | { 124 | if (defaultConfigValueTable.ContainsKey(key)) 125 | { 126 | defaultValue = defaultConfigValueTable[key]; 127 | } 128 | } 129 | 130 | return defaultValue; 131 | } 132 | 133 | /// 134 | /// Reads from .ini file. 135 | /// 136 | /// The section. 137 | /// The key. 138 | /// The value. 139 | private string ReadFromIniFile(string section, string key) 140 | { 141 | StringBuilder sb = new StringBuilder(255); 142 | 143 | int i = GetPrivateProfileString(section, key, string.Empty, sb, 255, configFilePath); 144 | 145 | return sb.ToString(); 146 | } 147 | 148 | /// 149 | /// Writes to .ini file. 150 | /// 151 | /// The section. 152 | /// The key. 153 | /// The value. 154 | private void WriteToIniFile(string section, string key, string value) 155 | { 156 | WritePrivateProfileString(section, key, value, configFilePath); 157 | } 158 | #endregion 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace Simon.SharpStreaming.Core 2 | { 3 | /// 4 | /// A class that keeps all kinds of constants. 5 | /// 6 | public class Constants 7 | { 8 | /// 9 | /// The library name. 10 | /// 11 | public static string LIB_NAME = "Sharp Streaming v"; 12 | 13 | /// 14 | /// The library version. 15 | /// 16 | public static string LIB_VERSION = "1.0.0.1"; 17 | 18 | /// 19 | /// The filter text of the media files. 20 | /// 21 | public static string FILTER_TEXT = "Video Files (*.avi; *.mov; *.mpg; *.mpeg; *.ts; *.wmv; *.vob; *.dat;)|*.avi; *.mov; *.mpg; *.mpeg; *.ts; *.wmv; *.vob; *.dat"; 22 | 23 | /// 24 | /// The stop alway of time gap, at present it is set to "0.01" seconds. 25 | /// 26 | public const double TIMEGAP_STOPALWAY = 0.01; 27 | 28 | #region The Const Commands For RTSP 29 | /// 30 | /// RTSP command of OPTIONS 31 | /// 32 | public const string RTSP_CMD_OPTIONS = "OPTIONS"; 33 | 34 | /// 35 | /// RTSP command of DESCRIBE 36 | /// 37 | public const string RTSP_CMD_DESCRIBE = "DESCRIBE"; 38 | 39 | /// 40 | /// RTSP command of SETUP 41 | /// 42 | public const string RTSP_CMD_SETUP = "SETUP"; 43 | 44 | /// 45 | /// RTSP command of PLAY 46 | /// 47 | public const string RTSP_CMD_PLAY = "PLAY"; 48 | 49 | /// 50 | /// RTSP command of PAUSE 51 | /// 52 | public const string RTSP_CMD_PAUSE = "PAUSE"; 53 | 54 | /// 55 | /// RTSP command of TEARDOWN 56 | /// 57 | public const string RTSP_CMD_TEARDOWN = "TEARDOWN"; 58 | #endregion 59 | 60 | #region The Constants For RTSP 61 | /// 62 | /// RTSP user agent header 63 | /// 64 | public static readonly string USER_AGENT_HEADER = "RTSP Client -- Simon Huang"; 65 | 66 | /// 67 | /// RTSP version of 1.0 68 | /// 69 | public static readonly string RTSP_HEADER_VERSION = "RTSP/1.0"; 70 | 71 | /// 72 | /// RTSP status code of "200" 73 | /// 74 | public static readonly string RTSP_STATUS_CODE_OK = "200"; 75 | 76 | /// 77 | /// RTSP allow commands 78 | /// 79 | public static readonly string RTSP_ALLOW_COMMAND = "OPTIONS, DESCRIBE, SETUP, PLAY, PAUSE, TEARDOWN"; 80 | #endregion 81 | 82 | #region The Constants For Configuration 83 | /// 84 | /// The config file path. 85 | /// 86 | public static readonly string CONFIG_FILE_NAME = "\\Config.ini"; 87 | 88 | /// 89 | /// The config section of "General". 90 | /// 91 | public static readonly string CONFIG_SECTION_GENERAL = "General"; 92 | 93 | /// 94 | /// The config section of "Catalog". 95 | /// 96 | public static readonly string CONFIG_SECTION_CATALOG = "Catalog"; 97 | 98 | /// 99 | /// The config key of close mode of the server. 100 | /// 101 | public static readonly string CONFIG_KEY_CLOSEMODE = "CloseMode"; 102 | 103 | /// 104 | /// The config key of maximum connection count of the client session. 105 | /// 106 | public static readonly string CONFIG_KEY_MAXCONNECTIONCOUNT = "MaxConnectionCount"; 107 | 108 | /// 109 | /// The config key of maximum time-out of the client session. 110 | /// 111 | public static readonly string CONFIG_KEY_MAXSESSIONTIMEOUT = "MaxSessionTimeout"; 112 | 113 | /// 114 | /// The config key of server port. 115 | /// 116 | public static readonly string CONFIG_KEY_SERVERPORT = "ServerPortNumber"; 117 | 118 | /// 119 | /// The config key of file catalog. 120 | /// 121 | public static readonly string CONFIG_KEY_FILECATALOG = "FileCatalog"; 122 | #endregion 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/Enums.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Simon.SharpStreaming.Core 3 | { 4 | /// 5 | /// The enum of level to be shown. 6 | /// 7 | public enum MsgLevel 8 | { 9 | /// 10 | /// The debug level. 11 | /// 12 | Debug, 13 | 14 | /// 15 | /// The error level. 16 | /// 17 | Error, 18 | 19 | /// 20 | /// The warn level. 21 | /// 22 | Warn, 23 | 24 | /// 25 | /// The info level. 26 | /// 27 | Info 28 | } 29 | 30 | /// 31 | /// The enum of the client session state to make sure that 32 | /// a client session is active or not. 33 | /// This enum is used on server side. 34 | /// 35 | public enum ClientSessionState 36 | { 37 | /// 38 | /// The client session is active. 39 | /// 40 | Active, 41 | 42 | /// 43 | /// The client session is inactive. 44 | /// 45 | Inactive 46 | } 47 | 48 | /// 49 | /// The enum of the player state. 50 | /// This enum is used on client side. 51 | /// 52 | public enum PlayerState 53 | { 54 | /// 55 | /// The player is ready to play. 56 | /// 57 | Ready, 58 | 59 | /// 60 | /// The player is buffering. 61 | /// 62 | Buffering, 63 | 64 | /// 65 | /// The player is playing. 66 | /// 67 | Playing, 68 | 69 | /// 70 | /// The player is paused. 71 | /// 72 | Paused, 73 | 74 | /// 75 | /// The player is stopped. 76 | /// 77 | Stopped 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/RtpUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Simon.SharpStreaming.Core 4 | { 5 | /// 6 | /// A class that provides utility methods for RTP. 7 | /// 8 | public class RtpUtils 9 | { 10 | /// 11 | /// Generates random SSRC value. 12 | /// 13 | /// Returns random SSRC value. 14 | public static uint GenerateSSRC() 15 | { 16 | uint ssrc = (uint)Utils.GenerateRandomNumber(100000, int.MaxValue); 17 | 18 | return ssrc; 19 | } 20 | 21 | /// 22 | /// Generates random CNAME value. 23 | /// 24 | /// The CNAME value. 25 | public static string GenerateCNAME() 26 | { 27 | string CNAME = Guid.NewGuid().ToString(); 28 | 29 | return CNAME; 30 | } 31 | 32 | /// 33 | /// Generates the random sequence number. 34 | /// 35 | /// The random sequence number. 36 | public static int GenerateSeqNumber() 37 | { 38 | // The sequence number must be random because of security: 39 | int seqNumber = Utils.GenerateRandomNumber(1, 10000); 40 | 41 | return seqNumber; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/TExceptionEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | 4 | namespace Simon.SharpStreaming.Core 5 | { 6 | /// 7 | /// Holds the exception event arguments. 8 | /// 9 | public class TExceptionEventArgs : EventArgs 10 | { 11 | /// 12 | /// The exception message. 13 | /// 14 | public readonly string ExceptionMessage; 15 | 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The ex. 20 | public TExceptionEventArgs(Exception exception) 21 | { 22 | StringBuilder sb = new StringBuilder(); 23 | 24 | sb.Append("[TargetSite: "); 25 | sb.Append(exception.TargetSite); 26 | sb.Append("] "); 27 | sb.Append(exception.Message); 28 | 29 | this.ExceptionMessage = sb.ToString(); 30 | } 31 | 32 | /// 33 | /// Initializes a new instance of the class. 34 | /// 35 | /// The message. 36 | public TExceptionEventArgs(string message) 37 | { 38 | this.ExceptionMessage = message; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Common/TSocketEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Sockets; 3 | 4 | namespace Simon.SharpStreaming.Core 5 | { 6 | /// 7 | /// Holds the socket event arguments. 8 | /// 9 | public class TSocketEventArgs : EventArgs 10 | { 11 | /// 12 | /// The client socket of TCP. 13 | /// 14 | public readonly Socket ClientSocket; 15 | 16 | /// 17 | /// The received buffer. 18 | /// 19 | public readonly byte[] RecvBuffer; 20 | 21 | /// 22 | /// The size of the received buffer. 23 | /// 24 | public readonly int RecvBufferSize; 25 | 26 | /// 27 | /// Initializes a new instance of the class. 28 | /// 29 | /// The socket. 30 | public TSocketEventArgs(Socket socket) 31 | { 32 | this.ClientSocket = socket; 33 | } 34 | 35 | /// 36 | /// Initializes a new instance of the class. 37 | /// 38 | /// The receive buffer. 39 | /// Size of the receive buffer. 40 | public TSocketEventArgs(byte[] recvBuffer, int recvBufferSize) 41 | { 42 | RecvBuffer = recvBuffer; 43 | RecvBufferSize = recvBufferSize; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Lib/Microsoft.DirectX.AudioVideoPlayback.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreaming.Core/Lib/Microsoft.DirectX.AudioVideoPlayback.dll -------------------------------------------------------------------------------- /SharpStreaming.Core/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过下列属性集 6 | // 控制。更改这些属性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("SharpStreaming.Core")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Simon Huang")] 12 | [assembly: AssemblyProduct("SharpStreaming.Core")] 13 | [assembly: AssemblyCopyright("Copyright © Simon Huang 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 属性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("b539fe78-2eac-4f17-9c9a-018b1a743a34")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 内部版本号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.*")] 36 | [assembly: AssemblyFileVersion("1.1.2.12")] 37 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Server/ClientSessionInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Simon.SharpStreaming.Core 4 | { 5 | public class ClientSessionInfo 6 | { 7 | /// 8 | /// Gets or sets the client session id. 9 | /// 10 | /// The client session id. 11 | public int ClientSessionId { get; set; } 12 | 13 | /// 14 | /// Gets or sets the client session IP. 15 | /// 16 | /// The client session IP. 17 | public string ClientSessionIP { get; set; } 18 | 19 | /// 20 | /// Gets or sets the client session port. 21 | /// 22 | /// The client session port. 23 | public int ClientSessionPort { get; set; } 24 | 25 | /// 26 | /// Gets or sets the session connect time. 27 | /// 28 | /// The session connect time. 29 | public DateTime SessionConnectTime { get; set; } 30 | 31 | /// 32 | /// Gets or sets the session last time. 33 | /// 34 | /// The session last time. 35 | public DateTime SessionLastTime { get; set; } 36 | 37 | /// 38 | /// Gets or sets the state of the session. 39 | /// 40 | /// The state of the session. 41 | public string SessionState { get; set; } 42 | 43 | /// 44 | /// Gets or sets the name of the stream. 45 | /// 46 | /// The name of the stream. 47 | public string StreamName { get; set; } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Server/MPEG2TransportFileServerMediaSession.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Simon.SharpStreaming.Core 6 | { 7 | public class MPEG2TransportFileServerMediaSession : ServerMediaSession 8 | { 9 | #region Private Member Fields 10 | /// 11 | /// The file name. 12 | /// 13 | private string fileName; 14 | 15 | /// 16 | /// The file duration. 17 | /// 18 | private double fileDuration; 19 | 20 | /// 21 | /// The file size. 22 | /// 23 | private long fileSize; 24 | #endregion 25 | 26 | #region Class Constructor 27 | /// 28 | /// Initializes a new instance of the class. 29 | /// 30 | /// Name of the file. 31 | public MPEG2TransportFileServerMediaSession(string fileName) 32 | : base(fileName) 33 | { 34 | this.fileName = fileName; 35 | } 36 | #endregion 37 | 38 | #region Public Override Methods 39 | /// 40 | /// Seeks the stream source. 41 | /// 42 | /// The input source. 43 | /// The seek NPT(Normal Play Time). 44 | public override void SeekStreamSource(MediaSource inputSource, double seekNPT) 45 | { 46 | if (inputSource != null) 47 | { 48 | inputSource.SeekWithinFile(seekNPT); 49 | } 50 | } 51 | 52 | /// 53 | /// Creates the stream source. 54 | /// 55 | /// The object of MediaSource. 56 | public override MediaSource CreateStreamSource() 57 | { 58 | string filePath = FileCatalog + fileName; 59 | MPEG2TransportStreamFileSource fileSource = new MPEG2TransportStreamFileSource(filePath); 60 | if (fileSource == null) 61 | { 62 | // Error 63 | Utils.OutputMessage(false, MsgLevel.Error, 64 | "MPEG2TransportFileServerMediaSession -- CreateStreamSource", 65 | "Could not create an instance of MPEG2TransportStreamFileSource!"); 66 | return null; 67 | } 68 | 69 | fileDuration = fileSource.Duration; 70 | fileSize = fileSource.FileSize; 71 | 72 | return fileSource; 73 | } 74 | 75 | /// 76 | /// Creates the RTP sink. 77 | /// 78 | /// The input source. 79 | /// The client RTP socket. 80 | /// The RtpSink object. 81 | public override RtpSink CreateRtpSink(MediaSource inputSource, ClientSocketBase clientRtpSocket) 82 | { 83 | int payloadType = 33; // MP2T video codec, defined in RFC 2250. 84 | 85 | RtpSink rtpSink = new RtpSink(payloadType, inputSource, clientRtpSocket); 86 | if (rtpSink == null) 87 | { 88 | // Error 89 | Utils.OutputMessage(false, MsgLevel.Error, 90 | "MPEG2TransportFileServerMediaSession -- CreateRtpSink", 91 | "Could not create an instance of RtpSink!"); 92 | } 93 | 94 | return rtpSink; 95 | } 96 | 97 | /// 98 | /// Gets the type of the media. 99 | /// 100 | /// The type of the media. 101 | public override string GetMediaType() 102 | { 103 | string mediaType = "Video"; 104 | 105 | return mediaType; 106 | } 107 | 108 | /// 109 | /// Gets the duration. 110 | /// 111 | /// The duration. 112 | public override double GetDuration() 113 | { 114 | return fileDuration; 115 | } 116 | 117 | /// 118 | /// Gets the size of the file. 119 | /// 120 | /// The file size. 121 | public override long GetFileSize() 122 | { 123 | return fileSize; 124 | } 125 | #endregion 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Server/MPEG2TransportStreamFileSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using Microsoft.DirectX.AudioVideoPlayback; 6 | 7 | namespace Simon.SharpStreaming.Core 8 | { 9 | public class MPEG2TransportStreamFileSource : MediaSource 10 | { 11 | #region Private Member Fields 12 | /// 13 | /// A lock of the file operation. 14 | /// 15 | private static object mutex = new object(); 16 | 17 | /// 18 | /// The object of the FileStream. 19 | /// 20 | private FileStream fileStream; 21 | 22 | private string fileName; 23 | 24 | private long fileSize; 25 | 26 | private double duration; 27 | #endregion 28 | 29 | #region Public Properties 30 | /// 31 | /// Gets the size of the file. 32 | /// 33 | /// The size of the file. 34 | public long FileSize 35 | { 36 | get { return this.fileSize; } 37 | } 38 | 39 | /// 40 | /// Gets the duration. 41 | /// 42 | /// The duration. 43 | public double Duration 44 | { 45 | get { return this.duration; } 46 | } 47 | #endregion 48 | 49 | #region Class Constructor 50 | /// 51 | /// Initializes a new instance of the class. 52 | /// 53 | /// Name of the file. 54 | public MPEG2TransportStreamFileSource(string fileName) 55 | { 56 | this.fileName = fileName; 57 | 58 | InitFileStream(); 59 | } 60 | #endregion 61 | 62 | #region Public Override Methods 63 | /// 64 | /// Seeks within the file. 65 | /// 66 | /// The seek NPT(Normal Play Time). 67 | public override void SeekWithinFile(double seekNPT) 68 | { 69 | lock (mutex) 70 | { 71 | try 72 | { 73 | long offset = (long)((seekNPT / duration) * fileSize); 74 | 75 | if (fileStream != null) 76 | { 77 | fileStream.Seek(offset, SeekOrigin.Begin); 78 | } 79 | } 80 | catch (System.Exception e) 81 | { 82 | Utils.OutputMessage(false, MsgLevel.Error, "MPEG2TransportStreamFileSource -- SeekWithinFile", e.Message); 83 | } 84 | } 85 | } 86 | 87 | /// 88 | /// Gets the next frame. 89 | /// 90 | /// The frame buffer. 91 | /// Size of the frame. 92 | /// The position. 93 | public override void GetNextFrame(ref byte[] frameBuffer, ref int frameSize, ref long position) 94 | { 95 | lock (mutex) 96 | { 97 | try 98 | { 99 | if (fileStream != null) 100 | { 101 | position = fileStream.Position; 102 | frameSize = fileStream.Read(frameBuffer, 0, PreferredFrameSize); 103 | } 104 | } 105 | catch (System.Exception e) 106 | { 107 | Utils.OutputMessage(false, MsgLevel.Error, "MPEG2TransportStreamFileSource -- GetNextFrame", e.Message); 108 | } 109 | } 110 | } 111 | 112 | /// 113 | /// Closes the media source. 114 | /// 115 | public override void CloseMediaSource() 116 | { 117 | if (fileStream != null) 118 | { 119 | fileStream.Close(); 120 | fileStream = null; 121 | } 122 | } 123 | #endregion 124 | 125 | #region Private Methods 126 | /// 127 | /// Initializes the file stream object. 128 | /// 129 | private void InitFileStream() 130 | { 131 | lock (mutex) 132 | { 133 | try 134 | { 135 | fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); 136 | fileSize = fileStream.Length; 137 | GetMediaDuration(); 138 | } 139 | catch (System.Exception e) 140 | { 141 | Utils.OutputMessage(false, MsgLevel.Error, "MPEG2TransportStreamFileSource -- InitFileStream", e.Message); 142 | } 143 | } 144 | } 145 | 146 | /// 147 | /// Gets the duration of the media file. 148 | /// 149 | private void GetMediaDuration() 150 | { 151 | using (Video video= new Video(fileName)) 152 | { 153 | duration = video.Duration; 154 | } 155 | } 156 | #endregion 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Server/MediaSource.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Simon.SharpStreaming.Core 3 | { 4 | /// 5 | /// A base class for the operation of the media file. 6 | /// 7 | public class MediaSource 8 | { 9 | #region Public Properties 10 | /// 11 | /// Gets or sets max the size of the frame. 12 | /// 13 | /// The max size of the frame. 14 | public int MaxFrameSize { get; set; } 15 | 16 | /// 17 | /// Gets or sets the size of the preferred frame. 18 | /// 19 | /// The size of the preferred frame. 20 | public int PreferredFrameSize { get; set; } 21 | #endregion 22 | 23 | #region Class Constructor 24 | /// 25 | /// Initializes a new instance of the class. 26 | /// 27 | public MediaSource() 28 | { 29 | MaxFrameSize = 1360; 30 | } 31 | #endregion 32 | 33 | #region Public Virtual Methods 34 | /// 35 | /// Seeks within the file. 36 | /// 37 | /// The seek NPT(Normal Play Time). 38 | public virtual void SeekWithinFile(double seekNPT) 39 | { 40 | // No implementation. 41 | } 42 | 43 | /// 44 | /// Gets the next frame. 45 | /// 46 | /// The frame buffer. 47 | /// Size of the frame. 48 | /// The position. 49 | public virtual void GetNextFrame(ref byte[] frameBuffer, ref int frameSize, ref long position) 50 | { 51 | // No implementation. 52 | } 53 | 54 | /// 55 | /// Closes the media source. 56 | /// 57 | public virtual void CloseMediaSource() 58 | { 59 | // No implementation. 60 | } 61 | #endregion 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Server/SocketListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | 5 | namespace Simon.SharpStreaming.Core 6 | { 7 | public class SocketListener 8 | { 9 | #region Private Member Fields 10 | /// 11 | /// Declares a server listen socket object for listening. 12 | /// 13 | private Socket listenSocket; 14 | 15 | /// 16 | /// The server port number. 17 | /// 18 | private int serverPort; 19 | 20 | /// 21 | /// The maximum length of the pending connections queue. 22 | /// 23 | private int maxBackLog = 10; 24 | 25 | /// 26 | /// The time to wait for a response, in microseconds. 27 | /// 28 | private int acceptListenTimeInterval = 20; 29 | #endregion 30 | 31 | #region Public Class Events 32 | public EventHandler ClientSocketAccepted; 33 | public EventHandler ExceptionOccurred; 34 | #endregion 35 | 36 | #region Class Constructor 37 | /// 38 | /// Initializes a new instance of the class. 39 | /// 40 | /// The port. 41 | public SocketListener(int port) 42 | { 43 | this.serverPort = port; 44 | } 45 | #endregion 46 | 47 | #region Public Methods 48 | /// 49 | /// Creates the server socket. 50 | /// 51 | /// success or failed 52 | public bool CreateServerSocket() 53 | { 54 | IPEndPoint iep = new IPEndPoint(IPAddress.Any, serverPort); 55 | 56 | try 57 | { 58 | // Initializes a new instance of the Socket class using the specified address family, socket type and protocol. 59 | listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 60 | // Associates a Socket with a local endpoint. 61 | listenSocket.Bind(iep); 62 | // Places a Socket in a listening state. 63 | listenSocket.Listen(maxBackLog); 64 | 65 | return true; 66 | } 67 | catch (System.Exception e) 68 | { 69 | this.OnExceptionOccurred(e); 70 | Utils.OutputMessage(false, MsgLevel.Error, e.TargetSite.ToString(), e.Message); 71 | 72 | return false; 73 | } 74 | } 75 | 76 | /// 77 | /// Starts the listening. 78 | /// 79 | /// The client TCP socket(null). 80 | public void StartListening(Socket clientSocket) 81 | { 82 | if (listenSocket == null) 83 | { 84 | CreateServerSocket(); 85 | } 86 | 87 | try 88 | { 89 | // Determines the status of the Socket. 90 | if (listenSocket.Poll(acceptListenTimeInterval, SelectMode.SelectRead)) 91 | { 92 | // Creates a new Socket for a newly created connection. 93 | clientSocket = listenSocket.Accept(); 94 | if (clientSocket != null && clientSocket.Connected) 95 | { 96 | this.OnClientSocketAccepted(clientSocket); 97 | } 98 | else 99 | { 100 | // The client socket is null or it was not connected, so we 101 | // try to close it. 102 | CloseClientSocket(clientSocket); 103 | } 104 | } 105 | } 106 | catch (System.Exception e) 107 | { 108 | CloseClientSocket(clientSocket); 109 | this.OnExceptionOccurred(e); 110 | Utils.OutputMessage(false, MsgLevel.Error, e.TargetSite.ToString(), e.Message); 111 | } 112 | } 113 | 114 | /// 115 | /// Closes the server socket if it is not null. 116 | /// 117 | public void CloseServerSocket() 118 | { 119 | if (listenSocket == null) 120 | { 121 | return; 122 | } 123 | 124 | try 125 | { 126 | // Closes the Socket connection and releases all associated resources. 127 | listenSocket.Close(); 128 | } 129 | catch (System.Exception e) 130 | { 131 | this.OnExceptionOccurred(e); 132 | Utils.OutputMessage(false, MsgLevel.Error, e.TargetSite.ToString(), e.Message); 133 | } 134 | finally 135 | { 136 | listenSocket = null; 137 | } 138 | } 139 | 140 | /// 141 | /// Closes the client socket if it is not null. 142 | /// 143 | /// The client socket. 144 | public void CloseClientSocket(Socket clientSocket) 145 | { 146 | if (clientSocket == null) 147 | { 148 | return; 149 | } 150 | 151 | try 152 | { 153 | // Disables sends and receives on a Socket. 154 | clientSocket.Shutdown(SocketShutdown.Both); 155 | 156 | // Closes the Socket connection and releases all associated resources. 157 | clientSocket.Close(); 158 | } 159 | catch 160 | { 161 | // Shut down it by force, ignores any exceptions. 162 | } 163 | } 164 | #endregion 165 | 166 | #region Protected Virtual Methods 167 | /// 168 | /// Called when [client socket accepted]. 169 | /// 170 | /// The socket. 171 | protected virtual void OnClientSocketAccepted(Socket clientSocket) 172 | { 173 | EventHandler handler = this.ClientSocketAccepted; 174 | if (handler != null) 175 | { 176 | TSocketEventArgs e = new TSocketEventArgs(clientSocket); 177 | handler(this, e); 178 | } 179 | } 180 | 181 | /// 182 | /// Called when [exception occurred]. 183 | /// 184 | /// The ex. 185 | protected virtual void OnExceptionOccurred(Exception ex) 186 | { 187 | EventHandler handler = this.ExceptionOccurred; 188 | if (handler != null) 189 | { 190 | TExceptionEventArgs e = new TExceptionEventArgs(ex); 191 | handler(this, e); 192 | } 193 | } 194 | #endregion 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Server/StreamState.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Simon.SharpStreaming.Core 6 | { 7 | /// 8 | /// A class that represents the state of an ongoing stream. 9 | /// 10 | public class StreamState 11 | { 12 | #region Private Member Fields 13 | private RtpSink rtpSink; 14 | private MediaSource mediaSource; 15 | private ClientSocketBase clientRtcpSocket; 16 | 17 | private bool isCurrentlyPlaying; 18 | #endregion 19 | 20 | #region Public Properties 21 | /// 22 | /// Gets the sink. 23 | /// 24 | /// The rtp sink. 25 | public RtpSink Sink 26 | { 27 | get { return this.rtpSink; } 28 | } 29 | 30 | /// 31 | /// Gets the source. 32 | /// 33 | /// The media source. 34 | public MediaSource Source 35 | { 36 | get { return this.mediaSource; } 37 | } 38 | #endregion 39 | 40 | #region Class Constructor 41 | /// 42 | /// Initializes a new instance of the class. 43 | /// 44 | /// The RTP sink. 45 | /// The input source. 46 | /// The client RTCP socket. 47 | public StreamState(RtpSink rtpSink, MediaSource inputSource, ClientSocketBase clientRtcpSocket) 48 | { 49 | this.rtpSink = rtpSink; 50 | this.mediaSource = inputSource; 51 | this.clientRtcpSocket = clientRtcpSocket; 52 | } 53 | #endregion 54 | 55 | #region Public Methods 56 | /// 57 | /// Starts the playing. 58 | /// 59 | public void StartPlaying() 60 | { 61 | if (!isCurrentlyPlaying) 62 | { 63 | if (rtpSink != null) 64 | { 65 | rtpSink.StartPlaying(); 66 | isCurrentlyPlaying = true; 67 | } 68 | } 69 | } 70 | 71 | /// 72 | /// Pauses the playing. 73 | /// 74 | public void PausePlaying() 75 | { 76 | if (rtpSink != null) 77 | { 78 | rtpSink.StopPlaying(); 79 | isCurrentlyPlaying = false; 80 | } 81 | } 82 | 83 | /// 84 | /// Ends the playing. 85 | /// 86 | public void EndPlaying() 87 | { 88 | if (rtpSink != null) 89 | { 90 | rtpSink.EndPlaying(); 91 | } 92 | } 93 | #endregion 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Server/TClientSessionEventArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Simon.SharpStreaming.Core 4 | { 5 | /// 6 | /// Holds the client session event arguments. 7 | /// 8 | public class TClientSessionEventArgs : EventArgs 9 | { 10 | /// 11 | /// The client session info. 12 | /// 13 | public readonly ClientSessionInfo SessionInfo; 14 | 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | /// The session info. 19 | public TClientSessionEventArgs(ClientSessionInfo sessionInfo) 20 | { 21 | this.SessionInfo = sessionInfo; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SharpStreaming.Core/Settings.StyleCop: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SharpStreaming.Core/SharpStreaming.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {B0F1A8BF-5923-4C49-BA82-DE2AA4F239E2} 9 | Library 10 | Properties 11 | Simon.SharpStreaming.Core 12 | SharpStreaming.Core 13 | v3.5 14 | 512 15 | 16 | 17 | 18 | 19 | 3.5 20 | publish\ 21 | true 22 | Disk 23 | false 24 | Foreground 25 | 7 26 | Days 27 | false 28 | false 29 | true 30 | 0 31 | 1.0.0.%2a 32 | false 33 | false 34 | true 35 | 36 | 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | AllRules.ruleset 45 | 46 | 47 | pdbonly 48 | true 49 | bin\Release\ 50 | TRACE 51 | prompt 52 | 4 53 | AllRules.ruleset 54 | 55 | 56 | 57 | Lib\Microsoft.DirectX.AudioVideoPlayback.dll 58 | 59 | 60 | 61 | 3.5 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | False 106 | .NET Framework 3.5 SP1 Client Profile 107 | false 108 | 109 | 110 | False 111 | .NET Framework 3.5 SP1 112 | true 113 | 114 | 115 | False 116 | Windows Installer 3.1 117 | true 118 | 119 | 120 | 121 | 128 | -------------------------------------------------------------------------------- /SharpStreaming.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpStreamingServer", "SharpStreamingServer\SharpStreamingServer.csproj", "{EF015B1E-D832-41B5-89F6-E021B3724105}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpStreamingClient", "SharpStreamingClient\SharpStreamingClient.csproj", "{D6931E5A-6ABA-4076-B284-1443A6FB44F2}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpStreaming.Core", "SharpStreaming.Core\SharpStreaming.Core.csproj", "{B0F1A8BF-5923-4C49-BA82-DE2AA4F239E2}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {EF015B1E-D832-41B5-89F6-E021B3724105}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {EF015B1E-D832-41B5-89F6-E021B3724105}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {EF015B1E-D832-41B5-89F6-E021B3724105}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {EF015B1E-D832-41B5-89F6-E021B3724105}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {D6931E5A-6ABA-4076-B284-1443A6FB44F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {D6931E5A-6ABA-4076-B284-1443A6FB44F2}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {D6931E5A-6ABA-4076-B284-1443A6FB44F2}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {D6931E5A-6ABA-4076-B284-1443A6FB44F2}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {B0F1A8BF-5923-4C49-BA82-DE2AA4F239E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {B0F1A8BF-5923-4C49-BA82-DE2AA4F239E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {B0F1A8BF-5923-4C49-BA82-DE2AA4F239E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {B0F1A8BF-5923-4C49-BA82-DE2AA4F239E2}.Release|Any CPU.Build.0 = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | EndGlobal 33 | -------------------------------------------------------------------------------- /SharpStreamingClient/AboutForm.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Reflection; 3 | using System.Windows.Forms; 4 | 5 | namespace Simon.SharpStreamingClient 6 | { 7 | public partial class AboutForm : Form 8 | { 9 | #region Public Assembly Properties 10 | public string AssemblyTitle 11 | { 12 | get 13 | { 14 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); 15 | if (attributes.Length > 0) 16 | { 17 | AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; 18 | if (titleAttribute.Title != "") 19 | { 20 | return titleAttribute.Title; 21 | } 22 | } 23 | return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); 24 | } 25 | } 26 | 27 | public string AssemblyVersion 28 | { 29 | get 30 | { 31 | return Assembly.GetExecutingAssembly().GetName().Version.ToString(); 32 | } 33 | } 34 | 35 | public string AssemblyDescription 36 | { 37 | get 38 | { 39 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); 40 | if (attributes.Length == 0) 41 | { 42 | return ""; 43 | } 44 | return ((AssemblyDescriptionAttribute)attributes[0]).Description; 45 | } 46 | } 47 | 48 | public string AssemblyProduct 49 | { 50 | get 51 | { 52 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); 53 | if (attributes.Length == 0) 54 | { 55 | return ""; 56 | } 57 | return ((AssemblyProductAttribute)attributes[0]).Product; 58 | } 59 | } 60 | 61 | public string AssemblyCopyright 62 | { 63 | get 64 | { 65 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); 66 | if (attributes.Length == 0) 67 | { 68 | return ""; 69 | } 70 | return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; 71 | } 72 | } 73 | 74 | public string AssemblyCompany 75 | { 76 | get 77 | { 78 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); 79 | if (attributes.Length == 0) 80 | { 81 | return ""; 82 | } 83 | return ((AssemblyCompanyAttribute)attributes[0]).Company; 84 | } 85 | } 86 | #endregion 87 | 88 | public AboutForm() 89 | { 90 | InitializeComponent(); 91 | 92 | this.Text = string.Format("About {0}", AssemblyTitle); 93 | 94 | StringBuilder strBuilder = new StringBuilder(); 95 | strBuilder.Append("Product Name: {0}\r\n"); 96 | strBuilder.Append("Version: {1}\r\n"); 97 | strBuilder.Append("Author: {2}\r\n"); 98 | strBuilder.Append("Copyright: {3}\r\n"); 99 | strBuilder.Append("Description: {4}"); 100 | 101 | this.txtAboutInfo.Text = string.Format(strBuilder.ToString(), 102 | AssemblyProduct, AssemblyVersion, AssemblyCompany, 103 | AssemblyCopyright, AssemblyDescription); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /SharpStreamingClient/AboutForm.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Simon.SharpStreamingClient 2 | { 3 | partial class AboutForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm)); 32 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 33 | this.txtAboutInfo = new System.Windows.Forms.TextBox(); 34 | this.btnOK = new System.Windows.Forms.Button(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // pictureBox1 39 | // 40 | this.pictureBox1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.BackgroundImage"))); 41 | this.pictureBox1.Location = new System.Drawing.Point(-4, -1); 42 | this.pictureBox1.Name = "pictureBox1"; 43 | this.pictureBox1.Size = new System.Drawing.Size(395, 65); 44 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; 45 | this.pictureBox1.TabIndex = 0; 46 | this.pictureBox1.TabStop = false; 47 | // 48 | // txtAboutInfo 49 | // 50 | this.txtAboutInfo.BackColor = System.Drawing.SystemColors.ControlLightLight; 51 | this.txtAboutInfo.Location = new System.Drawing.Point(12, 70); 52 | this.txtAboutInfo.Multiline = true; 53 | this.txtAboutInfo.Name = "txtAboutInfo"; 54 | this.txtAboutInfo.ReadOnly = true; 55 | this.txtAboutInfo.Size = new System.Drawing.Size(363, 128); 56 | this.txtAboutInfo.TabIndex = 2; 57 | // 58 | // btnOK 59 | // 60 | this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; 61 | this.btnOK.Location = new System.Drawing.Point(300, 204); 62 | this.btnOK.Name = "btnOK"; 63 | this.btnOK.Size = new System.Drawing.Size(75, 23); 64 | this.btnOK.TabIndex = 1; 65 | this.btnOK.Text = "OK(&O)"; 66 | this.btnOK.UseVisualStyleBackColor = true; 67 | // 68 | // AboutForm 69 | // 70 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 71 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 72 | this.BackgroundImage = global::Simon.SharpStreamingClient.Properties.Resources.bg; 73 | this.ClientSize = new System.Drawing.Size(387, 239); 74 | this.Controls.Add(this.btnOK); 75 | this.Controls.Add(this.txtAboutInfo); 76 | this.Controls.Add(this.pictureBox1); 77 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 78 | this.MaximizeBox = false; 79 | this.MinimizeBox = false; 80 | this.Name = "AboutForm"; 81 | this.ShowInTaskbar = false; 82 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 83 | this.Text = "About..."; 84 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 85 | this.ResumeLayout(false); 86 | this.PerformLayout(); 87 | 88 | } 89 | 90 | #endregion 91 | 92 | private System.Windows.Forms.PictureBox pictureBox1; 93 | private System.Windows.Forms.TextBox txtAboutInfo; 94 | private System.Windows.Forms.Button btnOK; 95 | } 96 | } -------------------------------------------------------------------------------- /SharpStreamingClient/ColorSlider.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Simon.SharpStreamingClient 2 | { 3 | partial class ColorSlider 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // ColorSlider 34 | // 35 | this.Size = new System.Drawing.Size(200, 30); 36 | this.ResumeLayout(false); 37 | 38 | } 39 | 40 | #endregion 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SharpStreamingClient/ColorSlider.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | False 122 | 123 | -------------------------------------------------------------------------------- /SharpStreamingClient/OpenForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Simon.SharpStreamingClient 2 | { 3 | partial class OpenForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 32 | this.btnCancel = new System.Windows.Forms.Button(); 33 | this.btnOK = new System.Windows.Forms.Button(); 34 | this.btnBrowse = new System.Windows.Forms.Button(); 35 | this.txtUrl = new System.Windows.Forms.TextBox(); 36 | this.txtLocalFile = new System.Windows.Forms.TextBox(); 37 | this.rbUrl = new System.Windows.Forms.RadioButton(); 38 | this.rbLocal = new System.Windows.Forms.RadioButton(); 39 | this.groupBox1.SuspendLayout(); 40 | this.SuspendLayout(); 41 | // 42 | // groupBox1 43 | // 44 | this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 45 | | System.Windows.Forms.AnchorStyles.Left) 46 | | System.Windows.Forms.AnchorStyles.Right))); 47 | this.groupBox1.BackColor = System.Drawing.Color.Transparent; 48 | this.groupBox1.Controls.Add(this.btnCancel); 49 | this.groupBox1.Controls.Add(this.btnOK); 50 | this.groupBox1.Controls.Add(this.btnBrowse); 51 | this.groupBox1.Controls.Add(this.txtUrl); 52 | this.groupBox1.Controls.Add(this.txtLocalFile); 53 | this.groupBox1.Controls.Add(this.rbUrl); 54 | this.groupBox1.Controls.Add(this.rbLocal); 55 | this.groupBox1.Location = new System.Drawing.Point(12, 12); 56 | this.groupBox1.Name = "groupBox1"; 57 | this.groupBox1.Size = new System.Drawing.Size(402, 122); 58 | this.groupBox1.TabIndex = 0; 59 | this.groupBox1.TabStop = false; 60 | this.groupBox1.Text = "Open a local file or a network url"; 61 | // 62 | // btnCancel 63 | // 64 | this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 65 | this.btnCancel.Location = new System.Drawing.Point(321, 88); 66 | this.btnCancel.Name = "btnCancel"; 67 | this.btnCancel.Size = new System.Drawing.Size(75, 23); 68 | this.btnCancel.TabIndex = 6; 69 | this.btnCancel.Text = "Cancel"; 70 | this.btnCancel.UseVisualStyleBackColor = true; 71 | // 72 | // btnOK 73 | // 74 | this.btnOK.Location = new System.Drawing.Point(240, 88); 75 | this.btnOK.Name = "btnOK"; 76 | this.btnOK.Size = new System.Drawing.Size(75, 23); 77 | this.btnOK.TabIndex = 5; 78 | this.btnOK.Text = "OK"; 79 | this.btnOK.UseVisualStyleBackColor = true; 80 | this.btnOK.Click += new System.EventHandler(this.btnOK_Click); 81 | // 82 | // btnBrowse 83 | // 84 | this.btnBrowse.Location = new System.Drawing.Point(335, 17); 85 | this.btnBrowse.Name = "btnBrowse"; 86 | this.btnBrowse.Size = new System.Drawing.Size(61, 23); 87 | this.btnBrowse.TabIndex = 4; 88 | this.btnBrowse.Text = "Browse"; 89 | this.btnBrowse.UseVisualStyleBackColor = true; 90 | this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click); 91 | // 92 | // txtUrl 93 | // 94 | this.txtUrl.Location = new System.Drawing.Point(107, 50); 95 | this.txtUrl.Name = "txtUrl"; 96 | this.txtUrl.Size = new System.Drawing.Size(289, 21); 97 | this.txtUrl.TabIndex = 3; 98 | this.txtUrl.Text = "rtsp://192.168.2.180:554/test.ts"; 99 | // 100 | // txtLocalFile 101 | // 102 | this.txtLocalFile.Location = new System.Drawing.Point(107, 19); 103 | this.txtLocalFile.Name = "txtLocalFile"; 104 | this.txtLocalFile.Size = new System.Drawing.Size(222, 21); 105 | this.txtLocalFile.TabIndex = 2; 106 | // 107 | // rbUrl 108 | // 109 | this.rbUrl.AutoSize = true; 110 | this.rbUrl.Location = new System.Drawing.Point(6, 51); 111 | this.rbUrl.Name = "rbUrl"; 112 | this.rbUrl.Size = new System.Drawing.Size(95, 16); 113 | this.rbUrl.TabIndex = 1; 114 | this.rbUrl.Text = "Network Url:"; 115 | this.rbUrl.UseVisualStyleBackColor = true; 116 | this.rbUrl.CheckedChanged += new System.EventHandler(this.rbUrl_CheckedChanged); 117 | // 118 | // rbLocal 119 | // 120 | this.rbLocal.AutoSize = true; 121 | this.rbLocal.Checked = true; 122 | this.rbLocal.Location = new System.Drawing.Point(6, 20); 123 | this.rbLocal.Name = "rbLocal"; 124 | this.rbLocal.Size = new System.Drawing.Size(89, 16); 125 | this.rbLocal.TabIndex = 0; 126 | this.rbLocal.TabStop = true; 127 | this.rbLocal.Text = "Local File:"; 128 | this.rbLocal.UseVisualStyleBackColor = true; 129 | this.rbLocal.CheckedChanged += new System.EventHandler(this.rbLocal_CheckedChanged); 130 | // 131 | // OpenForm 132 | // 133 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 134 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 135 | this.BackgroundImage = global::Simon.SharpStreamingClient.Properties.Resources.bg; 136 | this.ClientSize = new System.Drawing.Size(426, 146); 137 | this.Controls.Add(this.groupBox1); 138 | this.MaximizeBox = false; 139 | this.MinimizeBox = false; 140 | this.Name = "OpenForm"; 141 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 142 | this.Text = "Open File"; 143 | this.groupBox1.ResumeLayout(false); 144 | this.groupBox1.PerformLayout(); 145 | this.ResumeLayout(false); 146 | 147 | } 148 | 149 | #endregion 150 | 151 | private System.Windows.Forms.GroupBox groupBox1; 152 | private System.Windows.Forms.RadioButton rbUrl; 153 | private System.Windows.Forms.RadioButton rbLocal; 154 | private System.Windows.Forms.Button btnBrowse; 155 | private System.Windows.Forms.TextBox txtUrl; 156 | private System.Windows.Forms.TextBox txtLocalFile; 157 | private System.Windows.Forms.Button btnCancel; 158 | private System.Windows.Forms.Button btnOK; 159 | } 160 | } -------------------------------------------------------------------------------- /SharpStreamingClient/OpenForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using Simon.SharpStreaming.Core; 4 | 5 | namespace Simon.SharpStreamingClient 6 | { 7 | public partial class OpenForm : Form 8 | { 9 | #region Private Member Fields 10 | private bool isLocalFile; 11 | private string fileNameOrUrl; 12 | #endregion 13 | 14 | #region Public Properties 15 | /// 16 | /// Gets a value indicating whether this instance is local file. 17 | /// 18 | /// 19 | /// true if this instance is local file; otherwise, false. 20 | /// 21 | public bool IsLocalFile 22 | { 23 | get { return this.isLocalFile; } 24 | } 25 | 26 | /// 27 | /// Gets the file name or URL. 28 | /// 29 | /// The file name or URL. 30 | public string FileNameOrUrl 31 | { 32 | get { return this.fileNameOrUrl; } 33 | } 34 | #endregion 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | public OpenForm() 40 | { 41 | InitializeComponent(); 42 | 43 | UpdateControlStatus(); 44 | } 45 | 46 | /// 47 | /// Handles the Click event of the btnBrowse control. 48 | /// 49 | /// The source of the event. 50 | /// The instance containing the event data. 51 | private void btnBrowse_Click(object sender, EventArgs e) 52 | { 53 | OpenFileDialog openFileDlg = new OpenFileDialog(); 54 | 55 | openFileDlg.Filter = Constants.FILTER_TEXT; 56 | openFileDlg.Title = "Open video file"; 57 | 58 | DialogResult dlgResult = openFileDlg.ShowDialog(); 59 | if (dlgResult == DialogResult.OK) 60 | { 61 | if (string.IsNullOrEmpty(openFileDlg.FileName)) 62 | { 63 | MessageBox.Show("The file name must not be empty, please open again!", "Information", 64 | MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 65 | } 66 | 67 | this.txtLocalFile.Text = openFileDlg.FileName; 68 | } 69 | } 70 | 71 | /// 72 | /// Handles the Click event of the btnOK control. 73 | /// 74 | /// The source of the event. 75 | /// The instance containing the event data. 76 | private void btnOK_Click(object sender, EventArgs e) 77 | { 78 | if (this.rbLocal.Checked) 79 | { 80 | if (string.IsNullOrEmpty(this.txtLocalFile.Text.Trim())) 81 | { 82 | MessageBox.Show("The local file name must not be empty, please browse a file!", "Information", 83 | MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 84 | 85 | return; 86 | } 87 | 88 | isLocalFile = true; 89 | fileNameOrUrl = this.txtLocalFile.Text.Trim(); 90 | } 91 | else if (this.rbUrl.Checked) 92 | { 93 | if (string.IsNullOrEmpty(this.txtUrl.Text.Trim())) 94 | { 95 | MessageBox.Show("The network url must not be empty, please input again!", "Information", 96 | MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 97 | 98 | return; 99 | } 100 | 101 | isLocalFile = false; 102 | fileNameOrUrl = this.txtUrl.Text.Trim(); 103 | } 104 | 105 | this.DialogResult = DialogResult.OK; 106 | } 107 | 108 | /// 109 | /// Handles the CheckedChanged event of the rbLocal control. 110 | /// 111 | /// The source of the event. 112 | /// The instance containing the event data. 113 | private void rbLocal_CheckedChanged(object sender, EventArgs e) 114 | { 115 | UpdateControlStatus(); 116 | } 117 | 118 | /// 119 | /// Handles the CheckedChanged event of the rbUrl control. 120 | /// 121 | /// The source of the event. 122 | /// The instance containing the event data. 123 | private void rbUrl_CheckedChanged(object sender, EventArgs e) 124 | { 125 | UpdateControlStatus(); 126 | } 127 | 128 | /// 129 | /// Updates the control status. 130 | /// 131 | private void UpdateControlStatus() 132 | { 133 | if (this.rbLocal.Checked) 134 | { 135 | this.txtLocalFile.Enabled = true; 136 | this.txtUrl.Enabled = false; 137 | this.btnBrowse.Enabled = true; 138 | } 139 | else 140 | { 141 | this.txtLocalFile.Enabled = false; 142 | this.txtUrl.Enabled = true; 143 | this.btnBrowse.Enabled = false; 144 | } 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /SharpStreamingClient/OpenForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SharpStreamingClient/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过下列属性集 6 | // 控制。更改这些属性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("SharpStreamingClient")] 9 | [assembly: AssemblyDescription("Sharp Streaming Client")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Simon Huang")] 12 | [assembly: AssemblyProduct("SharpStreamingClient")] 13 | [assembly: AssemblyCopyright("Copyright © Simon Huang 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 属性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("cbe5ea1c-df09-4b1c-a7be-02a5929ef851")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 内部版本号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.15")] 37 | -------------------------------------------------------------------------------- /SharpStreamingClient/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.296 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Simon.SharpStreamingClient.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Simon.SharpStreamingClient.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | internal static System.Drawing.Bitmap bg { 64 | get { 65 | object obj = ResourceManager.GetObject("bg", resourceCulture); 66 | return ((System.Drawing.Bitmap)(obj)); 67 | } 68 | } 69 | 70 | internal static System.Drawing.Bitmap statusbar_bg { 71 | get { 72 | object obj = ResourceManager.GetObject("statusbar_bg", resourceCulture); 73 | return ((System.Drawing.Bitmap)(obj)); 74 | } 75 | } 76 | 77 | internal static System.Drawing.Bitmap toolbar_about { 78 | get { 79 | object obj = ResourceManager.GetObject("toolbar_about", resourceCulture); 80 | return ((System.Drawing.Bitmap)(obj)); 81 | } 82 | } 83 | 84 | internal static System.Drawing.Bitmap toolbar_bg { 85 | get { 86 | object obj = ResourceManager.GetObject("toolbar_bg", resourceCulture); 87 | return ((System.Drawing.Bitmap)(obj)); 88 | } 89 | } 90 | 91 | internal static System.Drawing.Bitmap toolbar_open { 92 | get { 93 | object obj = ResourceManager.GetObject("toolbar_open", resourceCulture); 94 | return ((System.Drawing.Bitmap)(obj)); 95 | } 96 | } 97 | 98 | internal static System.Drawing.Bitmap toolbar_pause { 99 | get { 100 | object obj = ResourceManager.GetObject("toolbar_pause", resourceCulture); 101 | return ((System.Drawing.Bitmap)(obj)); 102 | } 103 | } 104 | 105 | internal static System.Drawing.Bitmap toolbar_play { 106 | get { 107 | object obj = ResourceManager.GetObject("toolbar_play", resourceCulture); 108 | return ((System.Drawing.Bitmap)(obj)); 109 | } 110 | } 111 | 112 | internal static System.Drawing.Bitmap toolbar_stop { 113 | get { 114 | object obj = ResourceManager.GetObject("toolbar_stop", resourceCulture); 115 | return ((System.Drawing.Bitmap)(obj)); 116 | } 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /SharpStreamingClient/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\res\Images\toolbar_stop.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\res\Images\bg.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\res\Images\statusbar_bg.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\res\Images\toolbar_about.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\res\Images\toolbar_bg.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | ..\res\Images\toolbar_open.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | ..\res\Images\toolbar_pause.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | 143 | ..\res\Images\toolbar_play.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 144 | 145 | -------------------------------------------------------------------------------- /SharpStreamingClient/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.296 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Simon.SharpStreamingClient.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SharpStreamingClient/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SharpStreamingClient/SharpStreamingClient.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {D6931E5A-6ABA-4076-B284-1443A6FB44F2} 9 | WinExe 10 | Properties 11 | Simon.SharpStreamingClient 12 | SharpStreamingClient 13 | v3.5 14 | 512 15 | client.ico 16 | 17 | 18 | 19 | 20 | 3.5 21 | publish\ 22 | true 23 | Disk 24 | false 25 | Foreground 26 | 7 27 | Days 28 | false 29 | false 30 | true 31 | 0 32 | 1.0.0.%2a 33 | false 34 | false 35 | true 36 | 37 | 38 | true 39 | full 40 | false 41 | ..\bin\Debug\ 42 | DEBUG;TRACE 43 | prompt 44 | 4 45 | AllRules.ruleset 46 | 47 | 48 | pdbonly 49 | true 50 | ..\bin\Release\ 51 | TRACE 52 | prompt 53 | 4 54 | AllRules.ruleset 55 | 56 | 57 | Simon.SharpStreamingClient.Program 58 | 59 | 60 | 61 | C:\Documents and Settings\Administrator\桌面\microsoft.directx.audiovideoplayback\X86\9.15.779.0000\Microsoft.DirectX.AudioVideoPlayback.dll 62 | 63 | 64 | 65 | 3.5 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Form 76 | 77 | 78 | AboutForm.cs 79 | 80 | 81 | Form 82 | 83 | 84 | ClientForm.cs 85 | 86 | 87 | Component 88 | 89 | 90 | ColorSlider.cs 91 | 92 | 93 | Form 94 | 95 | 96 | OpenForm.cs 97 | 98 | 99 | 100 | 101 | AboutForm.cs 102 | Designer 103 | 104 | 105 | ClientForm.cs 106 | Designer 107 | 108 | 109 | ColorSlider.cs 110 | Designer 111 | 112 | 113 | OpenForm.cs 114 | Designer 115 | 116 | 117 | ResXFileCodeGenerator 118 | Resources.Designer.cs 119 | Designer 120 | 121 | 122 | True 123 | Resources.resx 124 | True 125 | 126 | 127 | SettingsSingleFileGenerator 128 | Settings.Designer.cs 129 | 130 | 131 | True 132 | Settings.settings 133 | True 134 | 135 | 136 | 137 | 138 | {B0F1A8BF-5923-4C49-BA82-DE2AA4F239E2} 139 | SharpStreaming.Core 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | False 172 | .NET Framework 3.5 SP1 Client Profile 173 | false 174 | 175 | 176 | False 177 | .NET Framework 3.5 SP1 178 | true 179 | 180 | 181 | False 182 | Windows Installer 3.1 183 | true 184 | 185 | 186 | 187 | 194 | -------------------------------------------------------------------------------- /SharpStreamingClient/client.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/client.ico -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/about_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/about_top.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/bg.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/player.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/player.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/statusbar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/statusbar_bg.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/toolbar_about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/toolbar_about.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/toolbar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/toolbar_bg.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/toolbar_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/toolbar_open.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/toolbar_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/toolbar_pause.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/toolbar_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/toolbar_play.png -------------------------------------------------------------------------------- /SharpStreamingClient/res/Images/toolbar_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingClient/res/Images/toolbar_stop.png -------------------------------------------------------------------------------- /SharpStreamingClient/src/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Forms; 4 | 5 | namespace Simon.SharpStreamingClient 6 | { 7 | static class Program 8 | { 9 | /// 10 | /// The main entry point of the application. 11 | /// 12 | [STAThread] 13 | static void Main() 14 | { 15 | Application.EnableVisualStyles(); 16 | Application.SetCompatibleTextRenderingDefault(false); 17 | Application.Run(new ClientForm()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SharpStreamingServer/AboutForm.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Reflection; 3 | using System.Windows.Forms; 4 | 5 | namespace Simon.SharpStreamingServer 6 | { 7 | public partial class AboutForm : Form 8 | { 9 | #region Public Assembly Properties 10 | /// 11 | /// Gets the assembly title. 12 | /// 13 | /// The assembly title. 14 | public string AssemblyTitle 15 | { 16 | get 17 | { 18 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); 19 | if (attributes.Length > 0) 20 | { 21 | AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; 22 | if (titleAttribute.Title != string.Empty) 23 | { 24 | return titleAttribute.Title; 25 | } 26 | } 27 | return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); 28 | } 29 | } 30 | 31 | /// 32 | /// Gets the assembly version. 33 | /// 34 | /// The assembly version. 35 | public string AssemblyVersion 36 | { 37 | get 38 | { 39 | return Assembly.GetExecutingAssembly().GetName().Version.ToString(); 40 | } 41 | } 42 | 43 | /// 44 | /// Gets the assembly description. 45 | /// 46 | /// The assembly description. 47 | public string AssemblyDescription 48 | { 49 | get 50 | { 51 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); 52 | if (attributes.Length == 0) 53 | { 54 | return string.Empty; 55 | } 56 | return ((AssemblyDescriptionAttribute)attributes[0]).Description; 57 | } 58 | } 59 | 60 | /// 61 | /// Gets the assembly product. 62 | /// 63 | /// The assembly product. 64 | public string AssemblyProduct 65 | { 66 | get 67 | { 68 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); 69 | if (attributes.Length == 0) 70 | { 71 | return string.Empty; 72 | } 73 | return ((AssemblyProductAttribute)attributes[0]).Product; 74 | } 75 | } 76 | 77 | /// 78 | /// Gets the assembly copyright. 79 | /// 80 | /// The assembly copyright. 81 | public string AssemblyCopyright 82 | { 83 | get 84 | { 85 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); 86 | if (attributes.Length == 0) 87 | { 88 | return string.Empty; 89 | } 90 | return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; 91 | } 92 | } 93 | 94 | /// 95 | /// Gets the assembly company. 96 | /// 97 | /// The assembly company. 98 | public string AssemblyCompany 99 | { 100 | get 101 | { 102 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); 103 | if (attributes.Length == 0) 104 | { 105 | return string.Empty; 106 | } 107 | return ((AssemblyCompanyAttribute)attributes[0]).Company; 108 | } 109 | } 110 | #endregion 111 | 112 | /// 113 | /// Initializes a new instance of the class. 114 | /// 115 | public AboutForm() 116 | { 117 | InitializeComponent(); 118 | 119 | this.Text = string.Format("About {0}", AssemblyTitle); 120 | 121 | StringBuilder strBuilder = new StringBuilder(); 122 | strBuilder.Append("Product Name: {0}\r\n"); 123 | strBuilder.Append("Version: {1}\r\n"); 124 | strBuilder.Append("Author: {2}\r\n"); 125 | strBuilder.Append("Copyright: {3}\r\n"); 126 | strBuilder.Append("Description: {4}"); 127 | 128 | this.txtAboutInfo.Text = string.Format(strBuilder.ToString(), 129 | AssemblyProduct, AssemblyVersion, AssemblyCompany, 130 | AssemblyCopyright, AssemblyDescription); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /SharpStreamingServer/AboutForm.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Simon.SharpStreamingServer 2 | { 3 | partial class AboutForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm)); 32 | this.btnOK = new System.Windows.Forms.Button(); 33 | this.txtAboutInfo = new System.Windows.Forms.TextBox(); 34 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // btnOK 39 | // 40 | this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; 41 | this.btnOK.Location = new System.Drawing.Point(302, 206); 42 | this.btnOK.Name = "btnOK"; 43 | this.btnOK.Size = new System.Drawing.Size(75, 23); 44 | this.btnOK.TabIndex = 0; 45 | this.btnOK.Text = "OK(&O)"; 46 | this.btnOK.UseVisualStyleBackColor = true; 47 | // 48 | // txtAboutInfo 49 | // 50 | this.txtAboutInfo.BackColor = System.Drawing.SystemColors.ControlLightLight; 51 | this.txtAboutInfo.Location = new System.Drawing.Point(12, 71); 52 | this.txtAboutInfo.Multiline = true; 53 | this.txtAboutInfo.Name = "txtAboutInfo"; 54 | this.txtAboutInfo.ReadOnly = true; 55 | this.txtAboutInfo.Size = new System.Drawing.Size(365, 129); 56 | this.txtAboutInfo.TabIndex = 1; 57 | // 58 | // pictureBox1 59 | // 60 | this.pictureBox1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBox1.BackgroundImage"))); 61 | this.pictureBox1.Location = new System.Drawing.Point(-5, -1); 62 | this.pictureBox1.Name = "pictureBox1"; 63 | this.pictureBox1.Size = new System.Drawing.Size(398, 66); 64 | this.pictureBox1.TabIndex = 2; 65 | this.pictureBox1.TabStop = false; 66 | // 67 | // AboutForm 68 | // 69 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 70 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 71 | this.BackgroundImage = global::Simon.SharpStreamingServer.Properties.Resources.bg; 72 | this.ClientSize = new System.Drawing.Size(389, 241); 73 | this.Controls.Add(this.pictureBox1); 74 | this.Controls.Add(this.txtAboutInfo); 75 | this.Controls.Add(this.btnOK); 76 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 77 | this.MaximizeBox = false; 78 | this.MinimizeBox = false; 79 | this.Name = "AboutForm"; 80 | this.ShowInTaskbar = false; 81 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 82 | this.Text = "About..."; 83 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 84 | this.ResumeLayout(false); 85 | this.PerformLayout(); 86 | 87 | } 88 | 89 | #endregion 90 | 91 | private System.Windows.Forms.Button btnOK; 92 | private System.Windows.Forms.TextBox txtAboutInfo; 93 | private System.Windows.Forms.PictureBox pictureBox1; 94 | } 95 | } -------------------------------------------------------------------------------- /SharpStreamingServer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的常规信息通过下列属性集 6 | // 控制。更改这些属性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("SharpStreamingServer")] 9 | [assembly: AssemblyDescription("Sharp Streaming Server")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Simon Huang")] 12 | [assembly: AssemblyProduct("SharpStreamingServer")] 13 | [assembly: AssemblyCopyright("Copyright © Simon Huang 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 使此程序集中的类型 18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型, 19 | // 则将该类型上的 ComVisible 属性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("5542555e-1d5f-4520-91da-2a40239ff075")] 24 | 25 | // 程序集的版本信息由下面四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 内部版本号 30 | // 修订号 31 | // 32 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, 33 | // 方法是按如下所示使用“*”: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.23")] 37 | -------------------------------------------------------------------------------- /SharpStreamingServer/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.296 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Simon.SharpStreamingServer.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Simon.SharpStreamingServer.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | internal static System.Drawing.Bitmap bg { 64 | get { 65 | object obj = ResourceManager.GetObject("bg", resourceCulture); 66 | return ((System.Drawing.Bitmap)(obj)); 67 | } 68 | } 69 | 70 | internal static System.Drawing.Bitmap statusbar_bg { 71 | get { 72 | object obj = ResourceManager.GetObject("statusbar_bg", resourceCulture); 73 | return ((System.Drawing.Bitmap)(obj)); 74 | } 75 | } 76 | 77 | internal static System.Drawing.Bitmap toolbar_about { 78 | get { 79 | object obj = ResourceManager.GetObject("toolbar_about", resourceCulture); 80 | return ((System.Drawing.Bitmap)(obj)); 81 | } 82 | } 83 | 84 | internal static System.Drawing.Bitmap toolbar_bg { 85 | get { 86 | object obj = ResourceManager.GetObject("toolbar_bg", resourceCulture); 87 | return ((System.Drawing.Bitmap)(obj)); 88 | } 89 | } 90 | 91 | internal static System.Drawing.Bitmap toolbar_hide { 92 | get { 93 | object obj = ResourceManager.GetObject("toolbar_hide", resourceCulture); 94 | return ((System.Drawing.Bitmap)(obj)); 95 | } 96 | } 97 | 98 | internal static System.Drawing.Bitmap toolbar_quit { 99 | get { 100 | object obj = ResourceManager.GetObject("toolbar_quit", resourceCulture); 101 | return ((System.Drawing.Bitmap)(obj)); 102 | } 103 | } 104 | 105 | internal static System.Drawing.Bitmap toolbar_setting { 106 | get { 107 | object obj = ResourceManager.GetObject("toolbar_setting", resourceCulture); 108 | return ((System.Drawing.Bitmap)(obj)); 109 | } 110 | } 111 | 112 | internal static System.Drawing.Bitmap toolbar_start { 113 | get { 114 | object obj = ResourceManager.GetObject("toolbar_start", resourceCulture); 115 | return ((System.Drawing.Bitmap)(obj)); 116 | } 117 | } 118 | 119 | internal static System.Drawing.Bitmap toolbar_stop { 120 | get { 121 | object obj = ResourceManager.GetObject("toolbar_stop", resourceCulture); 122 | return ((System.Drawing.Bitmap)(obj)); 123 | } 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /SharpStreamingServer/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.296 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Simon.SharpStreamingServer.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SharpStreamingServer/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SharpStreamingServer/SettingsForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Simon.SharpStreamingServer 5 | { 6 | public partial class SettingsForm : Form 7 | { 8 | /// 9 | /// Initializes a new instance of the class. 10 | /// 11 | public SettingsForm() 12 | { 13 | InitializeComponent(); 14 | 15 | InitializeSettingsForm(); 16 | } 17 | 18 | /// 19 | /// Initializes the settings form. 20 | /// 21 | private void InitializeSettingsForm() 22 | { 23 | OptionsTreeNode optionsNode = new OptionsTreeNode("General", new GeneralControl("General Setting")); 24 | AddOptionsItem(optionsNode); 25 | 26 | optionsNode = new OptionsTreeNode("Catalog", new CatalogControl("Catalog Setting")); 27 | AddOptionsItem(optionsNode); 28 | } 29 | 30 | /// 31 | /// Adds the options item. 32 | /// 33 | /// The node. 34 | public void AddOptionsItem(TreeNode node) 35 | { 36 | if (tvOptions.Nodes.Count == 0) 37 | { 38 | tvOptions.Nodes.Add(node); 39 | tvOptions.SelectedNode = node; 40 | tvOptions.Select(); 41 | } 42 | else 43 | { 44 | tvOptions.Nodes.Add(node); 45 | } 46 | 47 | BaseControl control = ((OptionsTreeNode)node).OptionControl; 48 | control.Initialize(); 49 | } 50 | 51 | /// 52 | /// Removes the options item. 53 | /// 54 | /// The name. 55 | public void RemoveOptionsItem(string name) 56 | { 57 | if (tvOptions.Nodes == null) 58 | { 59 | return; 60 | } 61 | 62 | foreach (TreeNode node in tvOptions.Nodes) 63 | { 64 | if (string.Equals(node.Text, name)) 65 | { 66 | tvOptions.Nodes.Remove(node); 67 | if (node is OptionsTreeNode) 68 | { 69 | BaseControl control = ((OptionsTreeNode)node).OptionControl; 70 | if (pnlMain.Controls.Contains((control))) 71 | { 72 | pnlMain.Controls.RemoveAt(0); 73 | } 74 | } 75 | 76 | break; 77 | } 78 | 79 | this.RemoveOptionsItem(name); 80 | } 81 | } 82 | 83 | /// 84 | /// Sets the label text. 85 | /// 86 | /// The label text. 87 | private void SetLabelText(string labelText) 88 | { 89 | this.lblOptionsName.Text = labelText; 90 | } 91 | 92 | /// 93 | /// Handles the Click event of the btnOK control. 94 | /// 95 | /// The source of the event. 96 | /// The instance containing the event data. 97 | private void btnOK_Click(object sender, EventArgs e) 98 | { 99 | if (tvOptions.Nodes == null) 100 | { 101 | return; 102 | } 103 | 104 | foreach (TreeNode node in tvOptions.Nodes) 105 | { 106 | if (node is OptionsTreeNode) 107 | { 108 | BaseControl control = ((OptionsTreeNode)node).OptionControl; 109 | control.Apply(); 110 | } 111 | } 112 | 113 | this.Close(); 114 | } 115 | 116 | /// 117 | /// Handles the Click event of the btnCancel control. 118 | /// 119 | /// The source of the event. 120 | /// The instance containing the event data. 121 | private void btnCancel_Click(object sender, EventArgs e) 122 | { 123 | this.Close(); 124 | } 125 | 126 | /// 127 | /// Handles the AfterSelect event of the tvOptions control. 128 | /// 129 | /// The source of the event. 130 | /// The instance containing the event data. 131 | private void tvOptions_AfterSelect(object sender, TreeViewEventArgs e) 132 | { 133 | if (e.Node is OptionsTreeNode) 134 | { 135 | // Removes any controls: 136 | if (pnlMain.Controls.Count > 0) 137 | { 138 | pnlMain.Controls.RemoveAt(0); 139 | } 140 | 141 | BaseControl control = ((OptionsTreeNode)e.Node).OptionControl; 142 | 143 | // Adds the current panel to the main panel: 144 | pnlMain.Controls.Add(control); 145 | 146 | // Sets the name of the panel: 147 | this.SetLabelText(((OptionsTreeNode)e.Node).OptionName); 148 | } 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/about_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/about_top.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/bg.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/settings_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/settings_normal.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/settings_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/settings_selected.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/statusbar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/statusbar_bg.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/toolbar_about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/toolbar_about.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/toolbar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/toolbar_bg.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/toolbar_hide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/toolbar_hide.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/toolbar_quit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/toolbar_quit.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/toolbar_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/toolbar_setting.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/toolbar_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/toolbar_start.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Images/toolbar_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/res/Images/toolbar_stop.png -------------------------------------------------------------------------------- /SharpStreamingServer/res/Options/BaseControl.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | using Simon.SharpStreaming.Core; 4 | 5 | namespace Simon.SharpStreamingServer 6 | { 7 | public partial class BaseControl : UserControl 8 | { 9 | /// 10 | /// Declares the object of Config. 11 | /// 12 | private Config config; 13 | 14 | /// 15 | /// The name of the option. 16 | /// 17 | private readonly string optionName; 18 | 19 | /// 20 | /// Gets the config. 21 | /// 22 | /// The config. 23 | public Config MyConfig 24 | { 25 | get { return this.config; } 26 | } 27 | 28 | /// 29 | /// Gets the name of the option. 30 | /// 31 | /// The name of the option. 32 | public string OptionName 33 | { 34 | get { return this.optionName; } 35 | } 36 | 37 | /// 38 | /// Initializes a new instance of the class. 39 | /// 40 | public BaseControl() 41 | { 42 | InitializeComponent(); 43 | } 44 | 45 | /// 46 | /// Initializes a new instance of the class. 47 | /// 48 | /// The name. 49 | public BaseControl(string name) : base() 50 | { 51 | this.config = new Config(); 52 | 53 | this.optionName = name; 54 | } 55 | 56 | /// 57 | /// Initializes the settings. 58 | /// 59 | public virtual void Initialize() 60 | { 61 | // Implementation by default. 62 | } 63 | 64 | /// 65 | /// Applies the changes and saves them. 66 | /// 67 | public virtual void Apply() 68 | { 69 | // Implementation by default. 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /SharpStreamingServer/res/Options/BaseControl.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Simon.SharpStreamingServer 2 | { 3 | partial class BaseControl 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region 组件设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // BaseControl 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.BackColor = System.Drawing.SystemColors.Control; 38 | this.Name = "BaseControl"; 39 | this.Size = new System.Drawing.Size(339, 209); 40 | this.ResumeLayout(false); 41 | 42 | } 43 | 44 | #endregion 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SharpStreamingServer/res/Options/BaseControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SharpStreamingServer/res/Options/CatalogControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | using Simon.SharpStreaming.Core; 5 | 6 | namespace Simon.SharpStreamingServer 7 | { 8 | public partial class CatalogControl : BaseControl 9 | { 10 | private string fileCatalog; 11 | 12 | /// 13 | /// Initializes a new instance of the class. 14 | /// 15 | /// The name. 16 | public CatalogControl(string name) : base(name) 17 | { 18 | InitializeComponent(); 19 | } 20 | 21 | /// 22 | /// Initializes the settings. 23 | /// 24 | public override void Initialize() 25 | { 26 | fileCatalog = MyConfig.GetConfigValue(Constants.CONFIG_SECTION_CATALOG, Constants.CONFIG_KEY_FILECATALOG); 27 | 28 | this.txtFileCatalog.Text = fileCatalog; 29 | } 30 | 31 | /// 32 | /// Applies the changes and saves them. 33 | /// 34 | public override void Apply() 35 | { 36 | fileCatalog = this.txtFileCatalog.Text; 37 | 38 | MyConfig.SetConfigValue(Constants.CONFIG_SECTION_CATALOG, Constants.CONFIG_KEY_FILECATALOG, fileCatalog); 39 | } 40 | 41 | /// 42 | /// Handles the Click event of the btnBrowse control. 43 | /// 44 | /// The source of the event. 45 | /// The instance containing the event data. 46 | private void btnBrowse_Click(object sender, System.EventArgs e) 47 | { 48 | FolderBrowserDialog folderBrowserDlg = new FolderBrowserDialog(); 49 | folderBrowserDlg.Description = "Please select a folder directory:"; 50 | 51 | DialogResult dlgResult = folderBrowserDlg.ShowDialog(); 52 | if (dlgResult == DialogResult.OK) 53 | { 54 | string selectedPath = folderBrowserDlg.SelectedPath; 55 | if (string.IsNullOrEmpty(selectedPath)) 56 | { 57 | MessageBox.Show("Please select a folder!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 58 | } 59 | else 60 | { 61 | this.txtFileCatalog.Text = selectedPath; 62 | } 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /SharpStreamingServer/res/Options/CatalogControl.designer.cs: -------------------------------------------------------------------------------- 1 | namespace Simon.SharpStreamingServer 2 | { 3 | partial class CatalogControl 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region 组件设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 32 | this.btnBrowse = new System.Windows.Forms.Button(); 33 | this.txtFileCatalog = new System.Windows.Forms.TextBox(); 34 | this.label1 = new System.Windows.Forms.Label(); 35 | this.groupBox1.SuspendLayout(); 36 | this.SuspendLayout(); 37 | // 38 | // groupBox1 39 | // 40 | this.groupBox1.Controls.Add(this.btnBrowse); 41 | this.groupBox1.Controls.Add(this.txtFileCatalog); 42 | this.groupBox1.Controls.Add(this.label1); 43 | this.groupBox1.Location = new System.Drawing.Point(3, 3); 44 | this.groupBox1.Name = "groupBox1"; 45 | this.groupBox1.Size = new System.Drawing.Size(340, 200); 46 | this.groupBox1.TabIndex = 1; 47 | this.groupBox1.TabStop = false; 48 | // 49 | // btnBrowse 50 | // 51 | this.btnBrowse.Location = new System.Drawing.Point(8, 103); 52 | this.btnBrowse.Name = "btnBrowse"; 53 | this.btnBrowse.Size = new System.Drawing.Size(75, 23); 54 | this.btnBrowse.TabIndex = 3; 55 | this.btnBrowse.Text = "Browse.."; 56 | this.btnBrowse.UseVisualStyleBackColor = true; 57 | this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click); 58 | // 59 | // txtFileCatalog 60 | // 61 | this.txtFileCatalog.BackColor = System.Drawing.SystemColors.ControlLightLight; 62 | this.txtFileCatalog.Location = new System.Drawing.Point(8, 43); 63 | this.txtFileCatalog.Multiline = true; 64 | this.txtFileCatalog.Name = "txtFileCatalog"; 65 | this.txtFileCatalog.ReadOnly = true; 66 | this.txtFileCatalog.Size = new System.Drawing.Size(326, 44); 67 | this.txtFileCatalog.TabIndex = 2; 68 | // 69 | // label1 70 | // 71 | this.label1.AutoSize = true; 72 | this.label1.Location = new System.Drawing.Point(6, 17); 73 | this.label1.Name = "label1"; 74 | this.label1.Size = new System.Drawing.Size(83, 12); 75 | this.label1.TabIndex = 1; 76 | this.label1.Text = "File Catalog:"; 77 | // 78 | // CatalogControl 79 | // 80 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 81 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 82 | this.BackColor = System.Drawing.Color.Transparent; 83 | this.Controls.Add(this.groupBox1); 84 | this.Name = "CatalogControl"; 85 | this.Size = new System.Drawing.Size(421, 313); 86 | this.groupBox1.ResumeLayout(false); 87 | this.groupBox1.PerformLayout(); 88 | this.ResumeLayout(false); 89 | 90 | } 91 | 92 | #endregion 93 | 94 | private System.Windows.Forms.GroupBox groupBox1; 95 | private System.Windows.Forms.Label label1; 96 | private System.Windows.Forms.Button btnBrowse; 97 | private System.Windows.Forms.TextBox txtFileCatalog; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /SharpStreamingServer/res/Options/CatalogControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SharpStreamingServer/res/Options/GeneralControl.cs: -------------------------------------------------------------------------------- 1 | using Simon.SharpStreaming.Core; 2 | 3 | namespace Simon.SharpStreamingServer 4 | { 5 | public partial class GeneralControl : BaseControl 6 | { 7 | /// 8 | /// The close mode of the server. 9 | /// 10 | private string closeMode; 11 | 12 | /// 13 | /// The maximum connection count. 14 | /// 15 | private int maxConnectionCount; 16 | 17 | /// 18 | /// The maximum session time-out. 19 | /// 20 | private int maxSessionTimeout; 21 | 22 | /// 23 | /// The server port. 24 | /// 25 | private int serverPort; 26 | 27 | /// 28 | /// Initializes a new instance of the class. 29 | /// 30 | /// The name. 31 | public GeneralControl(string name) : base(name) 32 | { 33 | InitializeComponent(); 34 | } 35 | 36 | /// 37 | /// Initializes the settings. 38 | /// 39 | public override void Initialize() 40 | { 41 | string result = MyConfig.GetConfigValue(Constants.CONFIG_SECTION_GENERAL, Constants.CONFIG_KEY_CLOSEMODE); 42 | closeMode = result; 43 | 44 | result = MyConfig.GetConfigValue(Constants.CONFIG_SECTION_GENERAL, Constants.CONFIG_KEY_MAXCONNECTIONCOUNT); 45 | maxConnectionCount = Utils.StringToInteger(result); 46 | 47 | result = MyConfig.GetConfigValue(Constants.CONFIG_SECTION_GENERAL, Constants.CONFIG_KEY_MAXSESSIONTIMEOUT); 48 | maxSessionTimeout = Utils.StringToInteger(result); 49 | 50 | result = MyConfig.GetConfigValue(Constants.CONFIG_SECTION_GENERAL, Constants.CONFIG_KEY_SERVERPORT); 51 | serverPort = Utils.StringToInteger(result); 52 | 53 | if (closeMode.Equals("0")) 54 | { 55 | this.rbMin.Checked = true; 56 | } 57 | else 58 | { 59 | this.rbQuit.Checked = true; 60 | } 61 | 62 | this.numMaxConnCount.Value = (decimal)maxConnectionCount; 63 | this.numMaxTimeout.Value = (decimal)maxSessionTimeout; 64 | this.numServerPort.Value = (decimal)serverPort; 65 | } 66 | 67 | /// 68 | /// Applies the changes and saves them. 69 | /// 70 | public override void Apply() 71 | { 72 | if (this.rbMin.Checked) 73 | { 74 | closeMode = "0"; 75 | } 76 | else if (this.rbQuit.Checked) 77 | { 78 | closeMode = "1"; 79 | } 80 | 81 | maxConnectionCount = (int)this.numMaxConnCount.Value; 82 | maxSessionTimeout = (int)this.numMaxTimeout.Value; 83 | serverPort = (int)this.numServerPort.Value; 84 | 85 | MyConfig.SetConfigValue(Constants.CONFIG_SECTION_GENERAL, Constants.CONFIG_KEY_CLOSEMODE, closeMode); 86 | MyConfig.SetConfigValue(Constants.CONFIG_SECTION_GENERAL, Constants.CONFIG_KEY_MAXCONNECTIONCOUNT, maxConnectionCount); 87 | MyConfig.SetConfigValue(Constants.CONFIG_SECTION_GENERAL, Constants.CONFIG_KEY_MAXSESSIONTIMEOUT, maxSessionTimeout); 88 | MyConfig.SetConfigValue(Constants.CONFIG_SECTION_GENERAL, Constants.CONFIG_KEY_SERVERPORT, serverPort); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /SharpStreamingServer/res/Options/GeneralControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /SharpStreamingServer/src/OptionsTreeNode.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace Simon.SharpStreamingServer 4 | { 5 | /// 6 | /// A class that manages the options' nodes. 7 | /// 8 | public class OptionsTreeNode : TreeNode 9 | { 10 | /// 11 | /// The control that is related to the options tree node 12 | /// 13 | private BaseControl optionControl; 14 | 15 | /// 16 | /// Gets the name of the option. 17 | /// 18 | /// The name of the option. 19 | public string OptionName 20 | { 21 | get { return this.optionControl.OptionName; } 22 | } 23 | 24 | /// 25 | /// Gets the option control. 26 | /// 27 | /// The option control. 28 | public BaseControl OptionControl 29 | { 30 | get { return this.optionControl; } 31 | } 32 | 33 | /// 34 | /// Initializes a new instance of the class. 35 | /// 36 | /// Name of the node. 37 | /// The related control. 38 | public OptionsTreeNode(string nodeName, BaseControl relatedControl) : base(nodeName) 39 | { 40 | this.optionControl = relatedControl; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SharpStreamingServer/src/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Forms; 4 | 5 | namespace Simon.SharpStreamingServer 6 | { 7 | static class Program 8 | { 9 | /// 10 | /// The main entry point of the application. 11 | /// 12 | [STAThread] 13 | static void Main() 14 | { 15 | Application.EnableVisualStyles(); 16 | Application.SetCompatibleTextRenderingDefault(false); 17 | Application.Run(new ServerForm()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SharpStreamingServer/web_server.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/darkmi/SharpStreaming/ded2992a7ef4fae1f65474034414a6984b9a8823/SharpStreamingServer/web_server.ico --------------------------------------------------------------------------------