видео звонок в c # - PullRequest
       27

видео звонок в c #

3 голосов
/ 13 января 2011

Я хочу сделать приложение похожее на скайп, а основная проблема - работа с видео и аудио. Первая проблема заключается в том, как получить массив байтов видео (точнее, мне нужно получить байты, которые представляют видео, чтобы я мог отправить их через Интернет), и то же самое со звуком. Вторая проблема заключается в воспроизведении байтов, которые поступают с другого компьютера. Я думал сделать это в WPF. Я новичок в WPF (я немного потренировался и создал пару программ, среди которых базовая программа чата). Я делаю это для практики, и я хочу как можно больше самостоятельно кодировать, сервер, клиент, передачу данных и так далее ... Я искал в интернете, и мне кажется, что только одно решение, или, лучше сказать, выполнимое, - это использование DirectShow.

Чтобы добавить, я знаю, что камера и микрофон поддерживаются в Silverlight, и я пробовал это (на самом деле, я пытался разместить HTML-страницу с проектом silverlight в проекте WPF, в котором находился веб-браузер, мне удалось показать видео с моей веб-камеры), но я не знаю, как получить байты, представляющие видео.

Возможно ли это сделать с WPF или silverlight? Я буду очень благодарен за предложение любого решения, совета или полезных ссылок.

Ответы [ 6 ]

1 голос
/ 13 января 2011

Используя графы фильтров DirectShow, вы будете иметь прямой доступ к буферам изображения и звука с устройств ввода (таких как камеры и микрофоны) в виде массива байтов, выборка за выборкой.Вы сможете напрямую манипулировать данными, выбирать формат кодирования или сжатия (используя специальные фильтры), а также контролировать скорость передачи данных и синхронизацию.

Однако:

  • , если вы совершенно не знакомы с этой средой, это будет hard .Кроме того, я знаю, что это прекрасно работает с C ++, но я никогда не программировал ни одного приложения Directshow на C #.(Вы можете посмотреть так: Учебники CodeProject , темы MSDN DirectShow и тесты с использованием graphedit )

  • потоковая передача мультимедиа по сетии получать его с помощью Directshow нетривиально и может быть довольно больно.Сетевые рендеры и сетевые исходные фильтры доступны повсюду, но, на мой взгляд, их всегда сложно использовать.И в зависимости от вашего формата видео (H264, MPEG, MJPEG ...) и выбора сетевого протокола (RTSP, простой старый UDP ...) вам может понадобиться написать свои собственные фильтры потока / источника, что сложно иотнимает много времени.

Тем не менее, это ВОЗМОЖНО, и если вашей главной целью является практика с кодированием, то почему бы и нет!

(Никогда не использовал WPF, возможно, это действительно такпроще!)

1 голос
/ 13 января 2011

Я не могу говорить с WPF или Silverlight, но я сделал это в DirectShow, и это неприятно. Если вы хотите использовать .NET, есть оболочка с открытым исходным кодом, называемая DirectShow.NET, которая очень помогает, и это все еще боль в заднице.

Microsoft хорошо поработала с DirectShow и всем этим с Filter-Graph, но затем они как бы отбросили мяч и не обновляли его годами.

Я бы порекомендовал поискать другую технологию (хотя она, вероятно, работает на DirectShow), и мне было бы интересно услышать, что вы найдете.

0 голосов
/ 25 января 2011

Для всех, кто интересуется этой темой,

Проведя часы в поисках интернета, мне удалось найти решение, которое должно работать. С помощью Silverlight я делаю снимки, меняя их размеры до 160x120 (или меньше), а затем преобразую их с помощью imagetools. Один поток, который отвечает за фотосъемку, запускает захват, а когда он завершается (захват выполняется асинхронно, так что вам нужны семафоры), он спит 200 мс; это почти эквивалентно 5 кадрам в секунду. Я делаю все это, потому что у меня медленная пропускная способность загрузки, около 16 килобайт в секунду, поэтому мне нужно сжать один кадр настолько, насколько я могу. Результатом является низкая детализация изображения, но если вы используете прямоугольник 100х100 для его просмотра, это не так уж плохо. Я еще не пробовал это с интернетом, но, как я уже сказал, это должно работать. Я также пытался использовать методы сжатия, чтобы сжать изображение немного больше, если это возможно, но я не знаю, как использовать этот класс (что-то не работает), поэтому оставил это в другой раз. Теперь я просто хочу, чтобы это работало, а позже я постараюсь добиться лучшей производительности. О, еще одна вещь, я также должен решить проблему с передачей звука, и это требует много работы. Итак, услышь последнее.

0 голосов
/ 19 января 2011

Некоторые люди посоветовали мне попробовать сделать программу в Silverlight, поэтому я попробовал. Мне удалось подключить камеру к моему приложению, сделать снимки и отобразить их как видео, и это работает довольно круто (отдельный снимок отвечает за создание снимков. Он вызывает CaptureImageAsync и блокирует семафор до завершения захвата. После разблокировки он отображает захваченное изображение и спит в течение 100 мс (это необязательно, это на самом деле частота кадров - меньшее число означает лучшее видео, большее число - ну, это не будет видео, это будет похоже на слайд с изображением). Если кто-то заинтересован в посте кода здесь и я опубликую свой код).

Проблема, с которой я сейчас сталкиваюсь, - это преобразование изображений в формат JPEG (или другой формат), потому что в необработанном изображении используется около 300 КБ, и это неприемлемо, поскольку у вас есть как минимум 5 изображений в секунду, поэтому потребуется 1,5 Соединение для загрузки MBytes: D Я пытаюсь сделать это с помощью imagetools, и если есть какой-либо прогресс, я сообщу вам.

0 голосов
/ 17 января 2011

Дорогие все, Потратив много часов на то, чтобы понять, как работает DirectShow, я не нашел ни одного простого примера, как воспроизводить медиа, без каких-либо модификаций, просто играть. Но мне удалось сделать это в конце. Сейчас я кратко расскажу о том, как работает DirectShow. Чтобы воспроизвести что-либо (аудио или видео), вы должны сначала открыть их, распаковать (поскольку большинство из них используют какое-то сжатие для экономии места на диске), а затем отправить их на устройство, которое будет воспроизводить их. Конечно, в зависимости от форматов мультимедиа и т. Д., Может быть сделано больше шагов, но это простейшее объяснение системы. Все эти задачи выполняются фильтрами, а набор связанных фильтров составляет график фильтра. Может быть, это трудно понять, но я думаю, что, посмотрев этот пример, вы получите более четкое представление об этом. И сказать, что для некоторых форматов вам не нужно делать все, потому что фильтр графа делает это за вас. Он создает и подключает все необходимые фильтры и запускает их для вас.

Я забыл упомянуть, что я использовал библиотеку DirectShow.net, которая является открытым проектом SourceFourge, и которая действует как своего рода оболочка для DirectShow от Microsoft. Это очень полезно, потому что изначально DirectShow ограничен для использования только в C ++, но с DirectShow.net вы можете использовать его с C #, VB и, как говорится, «теоретически с любым языком .net». Принципы DirectShow.net такие же, как DirectShow, поэтому обучение начинается с одной веб-страницы: Веб-страница Microsoft . Чтобы использовать DirectShow.net в своем проекте, вы просто скачиваете библиотеку из SourceForge, открываете проект , добавляете ссылку на него и добавляете using DirectShowLib;. А также посетите их форум. В конце концов, имейте в виду, что вы изучаете принципы на веб-странице Microsoft или говорите, как все работает, но, используя DirectShow.net, вы учитесь на примерах или говорите, как использовать инструменты, которые вам нужны для выполнения различных задач. Образцы и библиотеку можно скачать по этой ссылке Вот пример кода для воспроизведения mp3 файла:

  class Example{
        ///....
        IGraphBuilder gb, gb1;
        IMediaControl mc, mc1;
        IVideoWindow vw;
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            gb = (IGraphBuilder) new FilterGraph();
            mc = (IMediaControl)gb; 
            //mc = gb as IMediaControl;//you can use this way instead of casting
            mc.RenderFile("C:\\test.mp3");
            mc.Run();

            gb1 = (IGraphBuilder)new FilterGraph();
            mc1 = (IMediaControl)gb1;
            vw = (IVideoWindow)gb1;
            vw.SetWindowPosition(0, 0, 320, 240);
            mc1.RenderFile("C:\\test.avi");
            mc1.Run();

         }

     }

Вы можете указать любой файл в любом месте на компьютере, но я сделал это так, чтобы было проще. Это простейшие примеры воспроизведения файлов, и для добавления любых других элементов управления вам необходимо узнать, как работает DirectShow.

Надеюсь, это поможет. :)

0 голосов
/ 14 января 2011

Всем, кому это интересно. Сначала скажу, что я читал о Directshow и медиа-фонде. Просто отметим, что программы DirectShow могут быть написаны только на C ++, а с помощью модели COM вы можете использовать вашу программу DirectShow с другими визуальными языками. Медиа-фонд кажется многообещающим, но он может работать только на Vista и Win 7. Я читал о библиотеке directshow.net, и нашел что-то, что, кажется, решение моих проблем :) На этой странице ссылка вы можете найти примеры, которые используют библиотеку directshow.net, и есть один пример с именем DxWebCam , который делает то, что я хочу сделать: от съемки видео и отправки через Интернет другому клиенту. Я постараюсь написать простой пример и дам вам знать о моем прогрессе. :)

...