/// <summary> /// This method is called when new RTP packet received. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event data.</param> private void m_pRTP_Stream_PacketReceived(object sender, RTP_PacketEventArgs e) { if (m_IsDisposed) { return; } try { AudioCodec codec = null; if (!m_pAudioCodecs.TryGetValue(e.Packet.PayloadType, out codec)) { // Unknown codec(payload value), skip it. return; } m_pActiveCodec = codec; // Audio-out not created yet, create it. if (m_pAudioOut == null) { m_pAudioOut = new AudioOut(m_pAudioOutDevice, codec.AudioFormat); } // Audio-out audio format not compatible to codec, recreate it. else if (!m_pAudioOut.AudioFormat.Equals(codec.AudioFormat)) { m_pAudioOut.Dispose(); m_pAudioOut = new AudioOut(m_pAudioOutDevice, codec.AudioFormat); } // Decode RTP audio frame and queue it for play out. byte[] decodedData = codec.Decode(e.Packet.Data, 0, e.Packet.Data.Length); m_pAudioOut.Write(decodedData, 0, decodedData.Length); } catch (Exception x) { if (!this.IsDisposed) { // Raise error event(We can't throw expection directly, we are on threadpool thread). OnError(x); } } }
/// <summary> /// Tworzy nową instancję klienta streamingu przez udp. /// </summary> /// <param name="video_window">Picturebox, w którym będzie wyświetlany obraz z kamery/streamu.</param> /// <param name="remote_ip">Zdalne IP serwera lub innego klienta.</param> public UdpStreamClient(PictureBox video_window, string remote_ip) { videoCapture = null; filters = new Filters(); microphone = null; speaker = null; streaming = false; recieving = false; inColor = true; timeInterval = 1000; framesCount = 0; videoWindow = video_window; audioCodec = new PCMU(); #region Wstępne ustawienia kompresji //################################################# encoderParams = new EncoderParameters(2); // Ustawiamy format kompresji na JPEG jpegEncoder = GetEncoder(ImageFormat.Jpeg); // Ustawiamy jakość obrazu this.SetImageQuality(20L); // Ustawiamy głębię kolorów this.SetImageColorDepth(8L); //################################################# #endregion // Wstępne ustawienia kompresji // Ustalanie lokalnego ip. strHostName = Dns.GetHostName(); this.ipHostEntry = Dns.GetHostByName(strHostName); this.localEndPoint = new IPEndPoint(ipHostEntry.AddressList[0], localUdpPort); // Ustawianie zdalnego ip. try { this.remoteEndPoint = new IPEndPoint(IPAddress.Parse(remote_ip), remoteUdpPort); } catch(FormatException ex) { MessageBox.Show(ex.Message, "Streaming"); } }
/// <summary> /// Stops receiving RTP audio and palying it out. /// </summary> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> public void Stop() { if (this.IsDisposed) { throw new ObjectDisposedException(this.GetType().Name); } if (!m_IsRunning) { return; } m_IsRunning = false; m_pRTP_Stream.PacketReceived -= new EventHandler <RTP_PacketEventArgs>(m_pRTP_Stream_PacketReceived); if (m_pAudioOut != null) { m_pAudioOut.Dispose(); m_pAudioOut = null; } }
/// <summary> /// This method is called when new RTP packet received. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event data.</param> private void m_pRTP_Stream_PacketReceived(object sender,RTP_PacketEventArgs e) { if(m_IsDisposed){ return; } try{ AudioCodec codec = null; if(!m_pAudioCodecs.TryGetValue(e.Packet.PayloadType,out codec)){ // Unknown codec(payload value), skip it. return; } m_pActiveCodec = codec; // Audio-out not created yet, create it. if(m_pAudioOut == null){ m_pAudioOut = new AudioOut(m_pAudioOutDevice,codec.AudioFormat); } // Audio-out audio format not compatible to codec, recreate it. else if(!m_pAudioOut.AudioFormat.Equals(codec.AudioFormat)){ m_pAudioOut.Dispose(); m_pAudioOut = new AudioOut(m_pAudioOutDevice,codec.AudioFormat); } // Decode RTP audio frame and queue it for play out. byte[] decodedData = codec.Decode(e.Packet.Data,0,e.Packet.Data.Length); m_pAudioOut.Write(decodedData,0,decodedData.Length); } catch(Exception x){ if(!this.IsDisposed){ // Raise error event(We can't throw expection directly, we are on threadpool thread). OnError(x); } } }
/// <summary> /// Stops receiving RTP audio and palying it out. /// </summary> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> public void Stop() { if(this.IsDisposed){ throw new ObjectDisposedException(this.GetType().Name); } if(!m_IsRunning){ return; } m_IsRunning = false; m_pRTP_Stream.PacketReceived -= new EventHandler<RTP_PacketEventArgs>(m_pRTP_Stream_PacketReceived); if(m_pAudioOut != null){ m_pAudioOut.Dispose(); m_pAudioOut = null; } }
/// <summary> /// Zatrzymuje odbieranie streamu jeżeli było wcześniej uruchomione. /// </summary> public void StopRecievingStream() { if (recieving) { this.listenThread.Abort(); this.udpClient.Close(); speaker.Dispose(); speaker = null; recieving = false; } }
/// <summary> /// Uruchamia odbieranie streamu jeżeli wcześniej nie zostało uruchomione. /// </summary> public void StartRecievingStream() { if(!recieving) { try { framesCount = 0; speaker = new AudioOut(AudioOut.Devices[0], 8000, 16, 1); this.localEndPoint.Port = localUdpPort; this.udpClient = new UdpClient(localUdpPort); this.listenThread = new Thread(new ThreadStart(ListenForData)); this.listenThread.Start(); recieving = true; } catch (Exception ex) { MessageBox.Show(ex.ToString()); return; } } }
/// <summary> /// Starts playing specified wave file for the specified number of times. /// </summary> /// <param name="stream">Wave stream.</param> /// <param name="count">Number of times to play.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception> public void Play(Stream stream, int count) { if (stream == null) { throw new ArgumentNullException("stream"); } if (m_IsPlaying) { Stop(); } m_IsPlaying = true; m_Stop = false; ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state) { using (BinaryReader waveFile = new BinaryReader(stream)) { WavReader wavReader = new WavReader(waveFile); if (!string.Equals(wavReader.Read_ChunkID(), "riff", StringComparison.InvariantCultureIgnoreCase)) { throw new ArgumentNullException("Invalid wave file, RIFF header missing."); } RIFF_Chunk riff = wavReader.Read_RIFF(); wavReader.Read_ChunkID(); fmt_Chunk fmt = wavReader.Read_fmt(); using (AudioOut player = new AudioOut(m_pOutputDevice, fmt.SampleRate, fmt.BitsPerSample, fmt.NumberOfChannels)) { long audioStartOffset = waveFile.BaseStream.Position; // Loop audio playing for specified times. for (int i = 0; i < count; i++) { waveFile.BaseStream.Position = audioStartOffset; // Read wave chunks. while (true) { string chunkID = wavReader.Read_ChunkID(); // EOS reached. if (chunkID == null || (waveFile.BaseStream.Length - waveFile.BaseStream.Position) < 4) { break; } // Wave data chunk. else if (string.Equals(chunkID, "data", StringComparison.InvariantCultureIgnoreCase)) { data_Chunk data = wavReader.Read_data(); int totalReaded = 0; byte[] buffer = new byte[8000]; while (totalReaded < data.ChunkSize) { if (m_Stop) { m_IsPlaying = false; return; } // Read audio block. int countReaded = waveFile.Read(buffer, 0, (int)Math.Min(buffer.Length, data.ChunkSize - totalReaded)); // Queue audio for play. player.Write(buffer, 0, countReaded); // Don't buffer more than 2x read buffer, just wait some data played out first. while (m_IsPlaying && player.BytesBuffered >= (buffer.Length * 2)) { Thread.Sleep(10); } totalReaded += countReaded; } } // unknown chunk. else { wavReader.SkipChunk(); } } } // Wait while audio playing is completed. while (m_IsPlaying && player.BytesBuffered > 0) { Thread.Sleep(10); } } } m_IsPlaying = false; })); }
private void Robot_FormClosed(object sender, FormClosedEventArgs e) { CloseFile(); //audio stream m_IsRunning = false; if (m_pRtpSession != null) { m_pRtpSession.Close(null); m_pRtpSession = null; } if (m_pWaveOut != null) { m_pWaveOut.Dispose(); m_pWaveOut = null; } if (m_pRecordStream != null) { m_pRecordStream.Dispose(); m_pRecordStream = null; } //audio stream //Robot1.ActiveForm.Dispose(); try { ThreadCheckStat.Abort(); mjpegsmall.smallcamClose(); } catch { } }
//Battery Monitor //AUDIO STREAM OLD private void m_pToggleRun_Click(object sender, EventArgs e) { if (m_IsRunning) { m_IsRunning = false; m_IsSendingTest = false; m_pRtpSession.Dispose(); m_pRtpSession = null; m_pWaveOut.Dispose(); m_pWaveOut = null; if (m_pRecordStream != null) { m_pRecordStream.Dispose(); m_pRecordStream = null; } m_pOutDevices.Enabled = true; m_pToggleRun.Text = "Start"; m_pRecord.Enabled = true; m_pRecordFile.Enabled = true; m_pRecordFileBrowse.Enabled = true; m_pRemoteIP.Enabled = false; m_pRemotePort.Enabled = false; m_pCodec.Enabled = false; m_pToggleMic.Text = "Send"; m_pToggleMic.Enabled = false; m_pSendTestSound.Enabled = false; m_pSendTestSound.Text = "Send"; m_pPlayTestSound.Enabled = false; m_pPlayTestSound.Text = "Play"; } else { if (m_pOutDevices.SelectedIndex == -1) { MessageBox.Show(this, "Please select output device !", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (m_pRecord.Checked && m_pRecordFile.Text == "") { MessageBox.Show(this, "Please specify record file !", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (m_pRecord.Checked) { m_pRecordStream = File.Create(m_pRecordFile.Text); } m_IsRunning = true; m_pWaveOut = new AudioOut(AudioOut.Devices[m_pOutDevices.SelectedIndex], 8000, 16, 1); m_pRtpSession = new RTP_MultimediaSession(RTP_Utils.GenerateCNAME()); // --- Debug ----- //wfrm_RTP_Debug frmRtpDebug = new wfrm_RTP_Debug(m_pRtpSession); //frmRtpDebug.Show(); //----------------- m_pRtpSession.CreateSession(new RTP_Address(IPAddress.Parse(m_pLocalIP.Text), (int)m_pLocalPort.Value, (int)m_pLocalPort.Value + 1), new RTP_Clock(0, 8000)); m_pRtpSession.Sessions[0].AddTarget(new RTP_Address(IPAddress.Parse(m_pRemoteIP.Text), (int)m_pRemotePort.Value, (int)m_pRemotePort.Value + 1)); m_pRtpSession.Sessions[0].NewSendStream += new EventHandler<RTP_SendStreamEventArgs>(m_pRtpSession_NewSendStream); m_pRtpSession.Sessions[0].NewReceiveStream += new EventHandler<RTP_ReceiveStreamEventArgs>(m_pRtpSession_NewReceiveStream); m_pRtpSession.Sessions[0].Payload = 8; m_pRtpSession.Sessions[0].Start(); m_pOutDevices.Enabled = false; m_pToggleRun.Text = "Stop"; m_pRecord.Enabled = false; m_pRecordFile.Enabled = false; m_pRecordFileBrowse.Enabled = false; m_pRemoteIP.Enabled = true; m_pRemotePort.Enabled = true; m_pCodec.Enabled = true; m_pToggleMic.Enabled = true; m_pSendTestSound.Enabled = true; m_pSendTestSound.Text = "Send"; m_pPlayTestSound.Enabled = true; m_pPlayTestSound.Text = "Play"; } m_pCodec.SelectedIndex = 0; }
private void btnRestartConnection_Click_1(object sender, RoutedEventArgs e) { if (cbLocalIp.SelectedIndex < 0) { MessageBox.Show("Choose local IP"); return; } IsConnected = true; InitializeClient(); InitializeServer(); /*InitializeSoundSender(); InitializeSoundReceiver();*/ if (m_IsRunning) { m_IsRunning = false; m_IsSendingTest = false; m_pRtpSession.Dispose(); m_pRtpSession = null; m_pWaveOut.Dispose(); m_pWaveOut = null; } else { m_IsRunning = true; switch (_selectedCodec) { case "PCMU": m_pActiveCodec = new PCMU(); break; case "PCMA": default: m_pActiveCodec = new PCMA(); break; } var selectedOutDevice = cbAudioOutDevices.SelectedItem as AudioOutDevice; m_pWaveOut = new AudioOut(selectedOutDevice, _samplesPerSecond, _bitsPerSample, 1); // 1 - one channel (mono) m_pRtpSession = new RTP_MultimediaSession(RTP_Utils.GenerateCNAME()); string localIp = cbLocalIp.SelectedItem.ToString(); string partnerIp = tbxPartnerIp.Text; int k = string.Compare(localIp, partnerIp); m_pRtpSession.CreateSession(new RTP_Address(IPAddress.Parse(cbLocalIp.SelectedItem.ToString()), (int)10000 + k * 500/*m_pLocalPort.Value*/, (int)/*m_pLocalPort.Value*/10000 + k * 500 + 1), new RTP_Clock(0, _samplesPerSecond)); m_pRtpSession.Sessions[0].AddTarget(new RTP_Address(IPAddress.Parse(tbxPartnerIp.Text), (int)/*m_pRemotePort.Value*/10000 - k * 500, (int)/*m_pRemotePort.Value*/10000 - k * 500 + 1)); m_pRtpSession.Sessions[0].NewSendStream += new EventHandler<RTP_SendStreamEventArgs>(m_pRtpSession_NewSendStream); m_pRtpSession.Sessions[0].NewReceiveStream += new EventHandler<RTP_ReceiveStreamEventArgs>(m_pRtpSession_NewReceiveStream); m_pRtpSession.Sessions[0].Payload = 0; m_pRtpSession.Sessions[0].Start(); m_pAudioCodecs = new Dictionary<int, AudioCodec>(); m_pAudioCodecs.Add(0, new PCMU()); m_pAudioCodecs.Add(8, new PCMA()); } }
/// <summary> /// Starts playing specified wave file for the specified number of times. /// </summary> /// <param name="stream">Wave stream.</param> /// <param name="count">Number of times to play.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stream</b> is null reference.</exception> public void Play(Stream stream,int count) { if(stream == null){ throw new ArgumentNullException("stream"); } if(m_IsPlaying){ Stop(); } m_IsPlaying = true; m_Stop = false; ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state){ using(BinaryReader waveFile = new BinaryReader(stream)){ WavReader wavReader = new WavReader(waveFile); if(!string.Equals(wavReader.Read_ChunkID(),"riff",StringComparison.InvariantCultureIgnoreCase)){ throw new ArgumentNullException("Invalid wave file, RIFF header missing."); } RIFF_Chunk riff = wavReader.Read_RIFF(); wavReader.Read_ChunkID(); fmt_Chunk fmt = wavReader.Read_fmt(); using(AudioOut player = new AudioOut(m_pOutputDevice,fmt.SampleRate,fmt.BitsPerSample,fmt.NumberOfChannels)){ long audioStartOffset = waveFile.BaseStream.Position; // Loop audio playing for specified times. for(int i=0;i<count;i++){ waveFile.BaseStream.Position = audioStartOffset; // Read wave chunks. while(true){ string chunkID = wavReader.Read_ChunkID(); // EOS reached. if(chunkID == null || (waveFile.BaseStream.Length - waveFile.BaseStream.Position) < 4){ break; } // Wave data chunk. else if(string.Equals(chunkID,"data",StringComparison.InvariantCultureIgnoreCase)){ data_Chunk data = wavReader.Read_data(); int totalReaded = 0; byte[] buffer = new byte[8000]; while(totalReaded < data.ChunkSize){ if(m_Stop){ m_IsPlaying = false; return; } // Read audio block. int countReaded = waveFile.Read(buffer,0,(int)Math.Min(buffer.Length,data.ChunkSize - totalReaded)); // Queue audio for play. player.Write(buffer,0,countReaded); // Don't buffer more than 2x read buffer, just wait some data played out first. while(m_IsPlaying && player.BytesBuffered >= (buffer.Length * 2)){ Thread.Sleep(10); } totalReaded += countReaded; } } // unknown chunk. else{ wavReader.SkipChunk(); } } } // Wait while audio playing is completed. while(m_IsPlaying && player.BytesBuffered > 0){ Thread.Sleep(10); } } } m_IsPlaying = false; })); }
/// <summary> /// This method is called when output device has changed. /// </summary> /// <param name="sender">Sender.</param> /// <param name="e">Event data.</param> private void m_pOutputDevice_SelectedIndexChanged(object sender,EventArgs e) { m_pPlayer = new AudioOut(AudioOut.Devices[m_pOutputDevice.SelectedIndex],8000,16,1); }