public void Init(string baseUri)
        {
            items = new List <Item>();

            CaptureDevice        defaultDevice = WasapiLoopbackCapture2.GetDefaultLoopbackCaptureDevice();
            List <CaptureDevice> devices       = WasapiLoopbackCapture2.GetLoopbackCaptureDevices();

            int itemId = 0;

            items.Add(new Item {
                Uri        = baseUri,
                Definition = DidlUtil.GenerateCaptureDeviceItem(++itemId, defaultDevice, baseUri)
            });

            int deviceId = 0;

            foreach (CaptureDevice captureDevice in devices)
            {
                if (captureDevice != defaultDevice)
                {
                    string uri = baseUri + "?id=" + deviceId;
                    items.Add(new Item {
                        Uri        = uri,
                        Definition = DidlUtil.GenerateCaptureDeviceItem(++itemId, captureDevice, uri)
                    });
                }
                deviceId++;
            }
        }
Beispiel #2
0
            public CaptureDeviceHandler(CaptureDevice device)
            {
                loopbackBuffers = new List <CircleBuffer>();

                loopbackCapture            = new WasapiLoopbackCapture2(device);
                loopbackCapture.WaveFormat = new WaveFormat(loopbackCapture.WaveFormat.SampleRate, 16, 2);

                Console.WriteLine(device.Name + " loopback capture source format: " + WaveFormat +
                                  " (" + Math.Round(WaveFormat.AverageBytesPerSecond * 8f / 1024 / 1024, 1) + " Mb/s)");
            }
        public void Start()
        {
            device.StartDevice();

            foreach (IPEndPoint ipep in device.LocalIPEndPoints)
            {
                if (ipep.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    Console.WriteLine("DLNA server STARTED listening @ " + ipep.ToString());
                    // create HTTP resource server endpoint
                    ipEndPoint = new IPEndPoint(ipep.Address, ipep.Port + 1);
                    break;
                }
            }

            S1 = HttpBaseURL + "capture";

            S2 = DidlUtil.BeginDidl();

            CaptureDevice        defaultDevice = WasapiLoopbackCapture2.GetDefaultLoopbackCaptureDevice();
            List <CaptureDevice> devices       = WasapiLoopbackCapture2.GetLoopbackCaptureDevices();

            S2 += GenerateCaptureDeviceEntry(1, defaultDevice, S1);

            int id = 0;

            foreach (CaptureDevice captureDevice in devices)
            {
                if (captureDevice != defaultDevice)
                {
                    S2 += GenerateCaptureDeviceEntry(id + 2, captureDevice, S1 + "?id=" + id);
                }
                id++;
            }

            S2     += DidlUtil.EndDidl();
            S2count = (uint)devices.Count;
        }
Beispiel #4
0
        public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
        {
            if (!request.Uri.AbsolutePath.StartsWith("/capture"))
            {
                return(false);
            }
            HttpServerUtil.DebugPrintRequest(request);

            HttpInputItem        deviceIdParam = request.Param["id"];
            CaptureDevice        device;
            CaptureDeviceHandler captureDevice;

            // First, get the specified lowlevel capture device
            if (deviceIdParam.Count == 1)
            {
                device = WasapiLoopbackCapture2.GetLoopbackCaptureDevices()[int.Parse(deviceIdParam.Value)];
            }
            else
            {
                device = WasapiLoopbackCapture2.GetDefaultLoopbackCaptureDevice();
            }

            // Then, get the capture device handler
            if (captureDevices.ContainsKey(device))
            {
                captureDevice = captureDevices[device];
            }
            else
            {
                captureDevice = new CaptureDeviceHandler(device);
                captureDevices.Add(device, captureDevice);
            }

            response.ContentLength = long.MaxValue;
            response.ContentType   = String.Format("audio/L16;rate={0};channels={1}",
                                                   captureDevice.WaveFormat.SampleRate,
                                                   captureDevice.WaveFormat.Channels);
            response.AddHeader("TransferMode.DLNA.ORG", "Streaming");
            response.AddHeader("Server", "UPnP/1.0 DLNADOC/1.50 LAB/1.0");
            response.AddHeader("icy-name", "Local Audio Broadcast");

            // create local output buffers
            CircleBuffer captureBuffer = new CircleBuffer(BUFFER_SIZE);

            byte[] buffer         = new byte[BUFFER_SIZE];
            byte[] emptiness100ms = new byte[captureDevice.WaveFormat.SampleRate / 10
                                             * captureDevice.WaveFormat.Channels
                                             * (captureDevice.WaveFormat.BitsPerSample / 8)];

            // register buffer for being filled with loopback samples
            captureDevice.Add(captureBuffer);

            IDataSource data = captureBuffer;

            EventHandler <TrackInfoChangedEventArgs> trackInfoHandler = null;

            if (request.Headers["Icy-MetaData"] == "1")
            {
                ShoutcastMetadataEmbedder me = new ShoutcastMetadataEmbedder(
                    captureDevice.WaveFormat.SampleRate * 2, // 1 second interval
                    captureBuffer);
                response.ProtocolVersion = "ICY";
                response.AddHeader("icy-metaint", me.Interval + "");
                data = me;
                me.SetTrackInfo(trackInfoProvider.TrackInfo);
                trackInfoHandler = new EventHandler <TrackInfoChangedEventArgs>(delegate(object sender, TrackInfoChangedEventArgs e) {
                    me.SetTrackInfo(e.TrackInfo);
                });
                trackInfoProvider.TrackInfoChanged += trackInfoHandler;
            }

            HttpServerUtil.DebugPrintResponse(response);
            Socket socket = HttpServerUtil.GetNetworkSocket(response);

            response.SendHeaders();

            int bytesRead = 0;

            while (socket.Connected)
            {
                Thread.Sleep(100);
                while (captureBuffer.Empty)
                {
                    //Thread.Sleep(200);
                    captureBuffer.Write(emptiness100ms, 0, emptiness100ms.Length);
                }
                lock (captureDevice.lockObject) {
                    bytesRead = data.Read(buffer, 0, buffer.Length);
                }
                //Console.WriteLine("buffer-{3} r {0} - {1} = {2}%", loopbackBuffer.FillLevel + bytesRead, bytesRead,
                //    (float)loopbackBuffer.FillLevel / loopbackBuffer.Length * 100, loopbackBuffer.GetHashCode());
                response.SendBody(buffer, 0, bytesRead);

                Console.WriteLine("sending {0} bytes = {1:0.00} secs", bytesRead, bytesRead /
                                  (double)captureDevice.loopbackCapture.WaveFormat.AverageBytesPerSecond);
            }

            if (trackInfoHandler != null)
            {
                trackInfoProvider.TrackInfoChanged -= trackInfoHandler;
            }

            // remove local output buffer
            captureDevice.Remove(captureBuffer);

            Console.WriteLine("request processing finished");

            return(true);
        }
        public override bool Process(HttpServer.IHttpRequest request, HttpServer.IHttpResponse response, HttpServer.Sessions.IHttpSession session)
        {
            if (!request.Uri.AbsolutePath.StartsWith("/capture"))
            {
                return(false);
            }
            HttpServerUtil.DebugPrintRequest(request);

            HttpInputItem        deviceIdParam = request.Param["id"];
            CaptureDevice        device;
            CaptureDeviceHandler captureDevice;

            // First, get the specified lowlevel capture device
            if (deviceIdParam.Count == 1)
            {
                device = WasapiLoopbackCapture2.GetLoopbackCaptureDevices()[int.Parse(deviceIdParam.Value)];
            }
            else
            {
                device = WasapiLoopbackCapture2.GetDefaultLoopbackCaptureDevice();
            }

            // Then, get the capture device handler
            if (captureDevices.ContainsKey(device))
            {
                captureDevice = captureDevices[device];
            }
            else
            {
                captureDevice = new CaptureDeviceHandler(device);
                captureDevices.Add(device, captureDevice);
            }

            HttpInputItem   formatParam = request.Param["format"];
            StreamingFormat format;

            if (formatParam.Count == 1)
            {
                format = StreamingFormat.GetFormat(formatParam.Value);
            }
            else
            {
                format = StreamingFormat.DefaultFormat;
            }

            response.ContentLength = long.MaxValue;
            response.ContentType   = format.GetFormatDescriptor(
                captureDevice.WaveFormat.SampleRate,
                captureDevice.WaveFormat.Channels);
            response.AddHeader("TransferMode.DLNA.ORG", "Streaming");
            response.AddHeader("Server", "UPnP/1.0 DLNADOC/1.50 LAB/1.0");
            response.AddHeader("icy-name", "Local Audio Broadcast");

            // create local output buffers
            CircleBuffer captureBuffer = new CircleBuffer(BUFFER_SIZE, new StreamingFormatTransform(format));

            byte[] buffer         = new byte[BUFFER_SIZE];
            byte[] emptiness100ms = new byte[captureDevice.WaveFormat.SampleRate / 10
                                             * captureDevice.WaveFormat.Channels
                                             * (captureDevice.WaveFormat.BitsPerSample / 8)];

            // register buffer for being filled with loopback samples
            captureDevice.Add(captureBuffer);

            IDataSource data = captureBuffer;

            EventHandler <TrackInfoChangedEventArgs> trackInfoHandler = null;

            if (request.Headers["Icy-MetaData"] == "1")
            {
                ShoutcastMetadataEmbedder me = new ShoutcastMetadataEmbedder(
                    captureDevice.WaveFormat.SampleRate * 2, // 1 second interval
                    captureBuffer);
                response.ProtocolVersion = "ICY";
                response.AddHeader("icy-metaint", me.Interval + "");
                data = me;
                me.SetTrackInfo(trackInfoProvider.TrackInfo);
                trackInfoHandler = new EventHandler <TrackInfoChangedEventArgs>(delegate(object sender, TrackInfoChangedEventArgs e) {
                    me.SetTrackInfo(e.TrackInfo);
                });
                trackInfoProvider.TrackInfoChanged += trackInfoHandler;
            }

            HttpServerUtil.DebugPrintResponse(response);
            Socket socket = HttpServerUtil.GetNetworkSocket(response);

            response.SendHeaders();

            if (format == StreamingFormat.WAV)
            {
                // build wav header
                byte[]       wavHeader = new byte[44];
                MemoryStream header    = new MemoryStream(wavHeader);
                using (BinaryWriter headerWriter = new BinaryWriter(header)) {
                    headerWriter.Write(Encoding.ASCII.GetBytes("RIFF"));
                    headerWriter.Write(uint.MaxValue - 8);
                    headerWriter.Write(Encoding.ASCII.GetBytes("WAVE"));
                    headerWriter.Write(Encoding.ASCII.GetBytes("fmt "));
                    headerWriter.Write(16);       // fmt chunk data size
                    headerWriter.Write((short)1); // format: 1 == PCM, 3 == PCM float
                    headerWriter.Write((short)captureDevice.WaveFormat.Channels);
                    headerWriter.Write(captureDevice.WaveFormat.SampleRate);
                    headerWriter.Write(captureDevice.WaveFormat.AverageBytesPerSecond);
                    headerWriter.Write((short)captureDevice.WaveFormat.BlockAlign);
                    headerWriter.Write((short)captureDevice.WaveFormat.BitsPerSample);
                    headerWriter.Write(Encoding.ASCII.GetBytes("data"));
                    headerWriter.Write(uint.MaxValue - 44);
                }

                // send header
                // To retain the correct Shoutcast metadata interval bytecount, the header must be written
                // to the intermediary captureBuffer instead of directly to the response.
                captureBuffer.Write(wavHeader, 0, wavHeader.Length);
            }

            // send audio data
            int bytesRead = 0;

            while (socket.Connected)
            {
                Thread.Sleep(100);
                while (captureBuffer.Empty)
                {
                    //Thread.Sleep(200);
                    captureBuffer.Write(emptiness100ms, 0, emptiness100ms.Length);
                }
                lock (captureDevice.lockObject) {
                    bytesRead = data.Read(buffer, 0, buffer.Length);
                }
                //Console.WriteLine("buffer-{3} r {0} - {1} = {2}%", loopbackBuffer.FillLevel + bytesRead, bytesRead,
                //    (float)loopbackBuffer.FillLevel / loopbackBuffer.Length * 100, loopbackBuffer.GetHashCode());
                response.SendBody(buffer, 0, bytesRead);

                Console.WriteLine("sending {0} bytes = {1:0.00} secs", bytesRead, bytesRead /
                                  (double)captureDevice.loopbackCapture.WaveFormat.AverageBytesPerSecond);
            }

            if (trackInfoHandler != null)
            {
                trackInfoProvider.TrackInfoChanged -= trackInfoHandler;
            }

            // remove local output buffer
            captureDevice.Remove(captureBuffer);

            Console.WriteLine("request processing finished");

            return(true);
        }