Как создать клиент Icecast, такой как Butt

Мне нужно создать клиент Icecast на C#. Основная цель этого — отправить входящий звук с двух аудиоустройств для трансляции через Icecast.

Когда я искал какое-то уже готовое решение, я нашел Butt, который был именно тем, что мне было нужно, но мне также нужно было отправить на Icecast два аудиоустройства по отдельности.

Я уже получаю аудиовход с двух микрофонов и сохраняю их в папке (по одному аудиофайлу для каждого микрофона). Теперь мне нужно отдельно транслировать два микрофона на Icecast.

Все это потому, что мне нужно транслировать два микрофона как радиостанцию ​​(по одной станции на каждый микрофон).

Основное решение примерно такое:

  • Микрофон 1 => Трансляция в Icecast, как Source Micro1 => Сохранение аудио, как в формате micro1.mp3 (работает).
  • Микрофон 2 => Трансляция в Icecast, как Source Micro2 => Сохранить звук, как в формате micro2.mp3 (работает).

Мне нужно знать, как я могу транслировать на icecast, я использую библиотеку NAudio, чтобы получить аудиовход и сохранить его.

РЕДАКТИРОВАТЬ: я общаюсь с Icecast из С#, это мой код:

public static void commIcecast(string url)
    {
        WebClient client = new WebClient();

        client.Headers.Add("content-type", "audio/mpeg");
        client.Headers.Add("Authorization", "Basic c291cmNlOmhhY2ttZQ==");
        client.Headers.Add("ice-name", "This is my server name");
        client.Headers.Add("ice-url", "http://www.google.com");
        client.Headers.Add("ice-genre", "Rock");
        client.Headers.Add("ice-description", "This is my server description");
        client.Headers.Add("ice-audio-info", "ice-samplerate=44100;ice-bitrate=128;ice-channels=2");

        Stream data = client.OpenRead(url);
        StreamReader reader = new StreamReader(data);
        string s = reader.ReadToEnd();
        Console.WriteLine(s);
        data.Close();
        reader.Close();
    }

Но я только что получил этот ответ от сервера Icecast:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Icecast Streaming Media Server</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0">
<h2>Icecast2 Status</h2>
<br><div class="roundcont">
<div class="roundtop"><img src="/corner_topleft.jpg" class="corner" style="display: none"></div>
<table border="0" width="100%" id="table1" cellspacing="0" cellpadding="4"><tr><td bgcolor="#656565">
<a class="nav" href="admin/">Administration</a><a class="nav" href="status.xsl">Server Status</a><a class="nav" href="server_version.xsl">Version</a>
</td></tr></table>
<div class="roundbottom"><img src="/corner_bottomleft.jpg" class="corner" style="display: none"></div>
</div>
<br><br>&nbsp;


<div class="poster">Support icecast development at <a class="nav" target="_blank" href="http://www.icecast.org">www.icecast.org</a>
</div>
</body>
</html>

Я пытался отправить "SOURCE /mp3test ICE/1.0", но метод Headers.Add не позволяет мне это сделать.

РЕДАКТИРОВАТЬ: я отправляю это через tcp в Icecast, но я не могу получить ответ, мне просто нужно знать, можно ли отправить его таким способом, если это прямо сейчас, мне придется переместить сообщение в проблемы tcp. Я не получаю никакого ответа от сервера Icecast, используя этот метод отправки.

            System.Net.IPAddress address = System.Net.IPAddress.Parse(url);

            socketServer = new TcpClient(url, port);
            NetworkStream networkStream = socketServer.GetStream();

            data = Encoding.ASCII.GetBytes("SOURCE /csharp ICE/1.0");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("content-type: audio/mpeg");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("Authorization: Basic c291cmNlOmhhY2ttZQ==");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("ice-name: lala");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("ice-url: localhost");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("ice-genre: Rock");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("ice-bitrate: 128");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("ice-private: 0");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("ice-public: 1");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("ice-description: This is my server description");
            networkStream.Write(data, 0, data.Length);

            data = Encoding.ASCII.GetBytes("ice-audio-info: ice-samplerate=44100;ice-bitrate=128;ice-channels=2");
            networkStream.Write(data, 0, data.Length);

            StreamReader reader = new StreamReader(networkStream);
            Console.WriteLine(reader.ReadToEnd());

С этим я могу подключиться к серверу Icecast, по крайней мере, количество подключенных клиентов увеличивается в глобальной статистике в Icecast, но затем соединение теряется, и я не могу получить никакого ответа.


person Juan Enrique Riquelme    schedule 23.11.2012    source источник
comment
К вашему сведению, Edcast может сделать это за вас. code.google.com/p/edcast-reborn   -  person Brad    schedule 24.11.2012
comment
Из-за некоторых проблем со временем я не мог продолжить работу с клиентом. Но Эдкаст сделал всю работу за меня.   -  person Juan Enrique Riquelme    schedule 05.03.2013
comment
Вы должны сделать клиент IceCast? Не могли бы вы показать это, пожалуйста, помогите   -  person zerpico    schedule 04.12.2016


Ответы (2)


Во-первых, вам нужно закодировать захваченный звук с помощью кодека. MP3 популярен и хорошо поддерживается. aacPlus хорошо поддерживается (но не так сильно, как MP3) и в большинстве случаев обеспечивает лучшую степень сжатия.

Я не верю, что NAudio поддерживает кодирование (пожалуйста, поправьте меня, если я ошибаюсь). Вам нужно будет посмотреть что-то вроде FFMPEG (доступен широкий выбор кодеков) или LAME (качественный кодек MP3). В качестве бонуса, если вы используете FFMPEG, он может захватывать исходники DirectShow, поэтому вам нужно только написать код для получения данных из STDOUT. (Обратите внимание, что здесь возможны проблемы с лицензированием, как с исходным кодом библиотек, так и с патентами на кодеки.)

Теперь, когда вы закодировали аудиоданные, вам нужно реализовать исходный протокол Icecast. Для этого см. мой ответ здесь: https://stackoverflow.com/a/9985297/362536

person Brad    schedule 24.11.2012
comment
Я не уверен в поддержке кодирования NAudio, но я получаю звук с двух входов и преобразовываю его в формат MP3/OGG/WAV, я не знаю, отвечает ли это на ваш вопрос о NAudio (я немного нуб в кодировании/звуке). Я уже проверил ваш ответ, но как я могу реализовать это в программе на С#? - person Juan Enrique Riquelme; 26.11.2012
comment
Если вы уже кодируете в MP3, этого достаточно. Возьмите выходные данные вашего MP3-кодировщика и отправьте их прямо на сервер Icecast по мере кодирования. Информацию об исходном протоколе можно найти по ссылке в моем ответе. Если у вас есть конкретные вопросы (например, об открытии TCP-соединения и отправке данных), вам следует задавать эти вопросы отдельно и индивидуально. Здесь много всего, и невозможно понять, с чем у вас проблемы, как по одному целому вопросу. Пожалуйста, дайте мне знать, если вы не знаете, как начать, и я могу обрисовать в общих чертах, что вам нужно сделать. - person Brad; 26.11.2012
comment
Хорошо, это прекрасно. Итак, позвольте мне посмотреть, правильно ли я понял: Первое: Получите кодирование MP3 (сделано). Второе: отправить информацию по протоколу IceCast (закодированное аудио) в Icecast через HTTPS-запрос? (подскажите, если я ошибаюсь, пожалуйста). - person Juan Enrique Riquelme; 26.11.2012
comment
Icecast не использует HTTPS. Он использует собственный проприетарный протокол. Теперь заголовки, которые вы отправляете в Icecast, очень похожи на заголовки HTTP, но это не одно и то же. Вы не найдете совместимой клиентской библиотеки HTTP. Вам необходимо создать TCP-соединение с сервером Icecast, отправить соответствующие заголовки, а затем начать отправку необработанных данных аудиопотока. - person Brad; 26.11.2012
comment
Я пытался отправить заголовки в Icecast, но я не уверен в структуре для отправки. Я уже подключаюсь к серверу, но не знаю, как отправлять заголовки на основе протокола. Можете ли вы привести пример на С#? - person Juan Enrique Riquelme; 26.11.2012
comment
Отправьте весь блок так же, как HTTP-запрос. Отправьте его как есть, дословно из первого блока на stackoverflow.com/a/9985297/362536. Я не знаю, какой метод вы используете для подключения к серверу, поэтому нет, я не могу привести вам пример на C#. Если вы не знаете, как отправлять данные через TCP-соединение, задайте для этого отдельный вопрос. - person Brad; 26.11.2012
comment
Как я уже говорил вам ранее, вы не можете просто использовать HTTP-клиент. Вы должны сами создать TCP-соединение и отправить данные заголовка. Вот почему то, что у вас выше, не работает. - person Brad; 27.11.2012
comment
Я сделал обновление, теперь я использую TCP-соединение, но не получаю ответа. - person Juan Enrique Riquelme; 27.11.2012
comment
@JuanEnriqueRiquelme, похоже, вы не отправляете окончания строк. Поставьте \r\n в конце строк и еще один в конце заголовков. - person Brad; 27.11.2012