Stream camera from android to android

Android Camera2 API от чайника, часть 3. Media Codec и стрим видео по UDP

Итак, со съемками фоточек и записью видео при помощи Camera2 API мы вроде бы, разобрались. Осталось только научиться передавать видеопоток c Android устройства страждущим получателям извне. Конечной целью, как уже неоднократно ранее говорилось, является интеллектуализация роботелеги — ставим на неё смартфон и так сказать, превращаем обезьяну в человека. В этом нам поможет Media Codec. И конечно, новое Camera2 API.

Кому интересно, прошу под кат.

Детали о проекте с роботележкой можно найти здесь, а мы пока займемся непосредственно стримингом видео с неё (вернее с прицепленного к ней Android смартфона) на персональную электронно-вычислительную машину.

Что нам для этого нужно?

Для того чтобы передать видео поток с экрана смартфона куда-либо ещё, как известно, его (поток) сначала необходимо преобразовать в подходящий ужатый формат (передавать покадрово выйдет слишком толсто), поставить time-stamps (временные метки) и отправить в бинарном виде получателю. Который произведёт обратную операцию декодирования.

Как раз этими низкоуровневыми чёрными делами и занимается класс Media Codec с 2013 года, с даты выхода Аndroid 4.3.

Другое дело, что раньше подступиться к кодированию видео, в отличие от сегодняшнего дня было не так-то просто. Чтобы вытащить картинку с камеры надо было использовать тонны загадочного кода в котором, как в заклинаниях якутских шаманов, единственная неточность могла привести к полному краху приложения. Добавьте к этому ещё предыдущее Camera API, где вместо готовых коллбэков приходилось ручками самостоятельно писать разные synchronized, а это занятие, скажем так, не для слабых духом.

И главное, издалека смотришь на рабочий код, вроде бы в общих чертах всё ясно. Начинаешь переносить по частям в свой проект — сыпется непонятно почему. А скорректировать не получается, потому что в деталях уже разобраться тяжело.

Да и от сплошных deprecated как-то не по себе. Короче говоря, непорядок

К счастью, для непонятливых гуглостроители ввели волшебную концепцию поверхности Surface, работая с которой, можно избежать низкоуровневых деталей. Какой ценой и что при этом теряет разработчик, мне как неспециалисту понять сложно, но зато теперь мы чуть ли не буквально можем сказать: «Android, возьми эту Surface на которую отображается видео с камеры и ничего там не меняя, ну вот как есть, закодируй и отправь дальше». И самое удивительное, что это работает. А с новым Camera2 API программа и сама знает, когда данные отправлять, коллбэки ж новые появились!

Так что теперь закодировать видео — раз плюнуть. Чем мы сейчас и займёмся.
Берём код из первой статьи и как обычно выкидываем из него всё кроме кнопочек и инициализации камеры.

И закончим прицеплением Media Codec

В прошлом посте мы выводили на Surface изображение с камеры и с него же писали видео при помощи MediaRecorder. Для этого мы просто указывали оба компонента в списке Surface.

Здесь то же самое, только вместо mMediaRecorder указываем:

Получается, что-то типа:

Что такое mEncoderSurface? А это та самая Surface, с которой будет работать Media Codec. Только для начала надо их обоих инициализировать примерно таким образом.

Теперь остается прописать единственный коллбэк. Когда Media Codec вдруг ощутит, что очередные данные для дальнейшей трансляции готовы, он нас об этом известит именно через него:

Байтовый массив outDate — это настоящее сокровище. В нём уже готовые кусочки закодированного в формате H264 видеопотока, с которым мы теперь можем делать всё, что захотим.

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

Но нам пока надо убедиться воочию, что данные в буфере это действительно видеопоток в формате H264. Поэтому, давайте мы их отправим в файл:

Пропишем в сетапе:

А в коллбэке где буфер:

Открываем приложение, жмем кнопку: «ВКЛЮЧИТЬ КАМЕРУ И СТРИМ». Начинается автоматически запись. Ждем немного и давим кнопку остановки.

Сохраненный файл штатно скорее всего не проиграется, поскольку формат не MP4, но если открыть его VLC плеером или сконвертить онлайн каким нибудь ONLINE CONVERT, то мы убедимся, что находимся на правильном пути. Правда изображение лежит на боку, но это поправимо.

Вообще, для каждого события записи, фотографирования или стрима, лучше, конечно, открывать каждый раз новую сессию, а старую закрывать. То есть, сначала мы включаем камеру и запускаем голое превью. Потом, если надо сделать снимок, превью закрываем и открываем превью, но уже с пристегнутым Image Reader. Если переходим на запись видео, то закрываем текущую сессию и запускаем сессию с превью и прицепленным к нему Media Recorder. Я этого не делал, чтобы не страдала наглядность кода, а вам решать, как удобнее самим.

А вот и сам код целиком.

И не забудьте про разрешения в манифесте.

Итак, мы убедились, что Media Codec работает. Но использовать его для записи видео в файл как-то бездуховно. С такой задачей гораздо лучше справится Media Recorder, да ещё и звук добавит. Поэтому файловую часть мы снова выкинем и добавим блок кода для стриминга видео в сеть по udp протоколу. Это тоже очень просто.

Читайте также:  Arm x86 отличия андроид

Сначала инициализируем UDP практически сервер.

А в том же коллбэке, где мы отправляли данные по готовности в поток для файла, отправим их теперь в виде дэйтаграмм в нашу домашнюю сеть (надеюсь она есть у всех?)

Казалось бы, но нет. Приложение при запуске скрашится. Видите-ли, системе не нравится, что в главном потоке мы отправляем всякие дэйтаграмм пакеты. Но для паники нет оснований. Во-первых мы хоть и в главном потоке, но работаем все равно асинхронно, то есть по срабатыванию коллбэка. Во-вторых отправка udp пакетов, такой же асинхронный процесс. Мы только говорим операционной системе, что неплохо было бы отправить пакетик, но, что мы всецело в этом деле полагаемся на неё. Поэтому, чтобы Android не бунтовал, то в начале программы добавим две строчки:

В общем и целом, получится следующая маленькая элегантная демонстрационная программка:

Не знаю, как у других, но на моем Red Note 7 даже видно, как скачут килобайты по нужному адресу

И таких udp сокетов можно наплодить множество, на сколько хватит пропускной способности сети. Главное, чтобы были адреса куда. Будет у вас широкоадресная рассылка.

Теперь пойдём искать нужный адрес на компьютере

Надо сказать, что не каждая компьютерная программа способна всосать и переварить видео поток формата H264 по единственному udp каналу без какой-либо дополнительной информации. Но некоторые могут. Это например крайне широко известный медиаплеер VLC. Это настолько крутая штука, что если начать описывать её возможности, то из статьи получится целая книга. Наверняка у вас она есть. Если нет, поставьте.

И судя по описанию команд для него, udp пакеты переварить этот плеер может.

Причём все эти source address и bind address, по идее и не нужны. Нужен только прослушиваемый порт.

И ещё, конечно, нужно не забыть про разрешение этот порт слушать (малварь же)

А вы знали, что Винда не дает сделать принтскрин с монитора ресурсов?

Или можно вообще брандмауэр отключить (не рекомендую)

Итак, преодолев эти тернии, запускаем VLC плеер с нашим адресом и наслаждаемся пустым экраном. Видео нет.

Как же так?

А вот так. У вас, наверно, стоит последняя версия VLC 3.08 Vetinari? Вот как раз, в этой версии udp объявлен deprecated и мало того выпилен нахрен.

Так-то логика разработчиков плеера понятна. Мало кому нужно использовать голый udp канал в наше время потому-что:

  • Нормально работает только в домашней неперегруженной сети. Стоит вам выйти во внешний мир и ненумерованные дэйтаграммы начнут теряться и приходить не в том порядке, в котором их послали. А для видео декодера это очень неприятно.
  • Незашифрован и легко компрометируется

Поэтому нормальные люди, конечно, используют протоколы более высокого уровня RTP и другие. То есть на пальцах — вы пишете сервер, который всё равно на низком уровне использует udp (для скорости), но параллельно обменивается управляющей информацией с клиентом кому он стримит видео. Какая там у него пропускная способность, не надо ли увеличить-уменьшить кэш для данных, какая детализация изображения оптимальна сейчас и так далее и тому подобное. Опять же звук тоже иногда нужен. А ему требуется, сами понимаете, синхронизация с видео.

Вон ребятам из Одноклассников даже пришлось свой протокол запилить для стриминга. Но у них задачи-то, конечно, гораздо более важные — рассылать видео с котиками десяткам миллионов домохозяек по всему миру. Там одним udp каналом не обойдёшься.
Но нам-то писать свой RTP сервер на андроиде как-то грустно. Наверное, можно найти даже готовый и даже бесплатный, но попробуем пока не усложнять сущностей. Просто возьмем версию VLC плеера, где udp стриминг ещё работал.

Устанавливаем вместо или рядом со старым (то есть новым VLC), как вам заблагорассудится.

Запускаем и снова видим пустой экран.

А все это потому, что мы явно не настроили использование кодека H264. Так-то VLC смог бы выбрать кодек автоматически, если бы имел дело с файлом (в настройках изначально, как раз и указан автоматический выбор). Но ему-то кидают байтовый поток по единственному каналу, а кодеков, которые VLC поддерживает десятки. Как ему разобраться, какой применить?

Поэтому устанавливаем кодек силой.

И вот теперь наслаждаемся трансляцией «живого» видео. Единственное, оно зачем-то лежит на боку, но это уже легко поправить в настройках видеоплеера.

А ещё можно просто запускать плеер из командной строки по такому ключу:

Источник

Stream camera from android to android

Camera Stream — WiFi IP Webcam
версия: 1.1

Последнее обновление программы в шапке: 04.07.2015

Краткое описание:
Прямая трансляция видео с камеры смартфона в реальном времени и просмотр на ПК, Mac, других смартфонах и планшетах.

Описание:
Camera Stream позволяет вашему смартфону или планшету снимать и транслировать потоковое видео со звуком как беспроводная сетевая IP камера с различными вариантами просмотра. Легко смотрите видео с камеры вашего мобильного на любом другой смартфоне, планшете или настольном ПК или Mac с веб-браузером. Транслируйте ваше видео в режиме реального времени по WiFi сети даже без доступа в интернет на любое количество других устройств. Camera Stream превращает ваш телефон в шпионскую камеру для легкого видеонаблюдения и вещания видео, аналогично реальной IP камере, так что вы можете использовать его как обычную няня-камеру, шпионскую камеру или для мониторинга домашних животных.

Особенности Camera Stream:
• Трансляция MJPEG видео потока по локальной Wi-Fi сети на множество устройств, ПК или Mac
• Просмотр видео камеры с аудио на многих устройствах одновременно
• Высокое качество потокового аудио в формате .wav
• Подсветка съёмки потокового видео в ночное время или темном помещении
• Защита паролем при доступе к видео потоку из веб-браузера
• Простота в использовании с простым пользовательским интерфейсом

Читайте также:  Content values in android

Пожалуйста, оцените приложение и оставьте комментарий в Google Play!

Официальный сайт приложения Camera Stream для Android:
http://vinternete.com

Краткий видео обзор Camera Stream с демонстрацией возможностей приложения:
https://www.youtube.com/watch?v=TRuODkzeowU

Требуется Android: 4.1 и выше
Русский интерфейс: Да

Скачать: версия: 1.1
CameraStream-1.1.apk ( 1.11 МБ )

Сообщение отредактировал trntfella — 04.07.15, 18:54

Источник

Stream camera from android to android

Still under development.

This is a Android Studio Project. It connects to a usb camera from your Android Device. (OTG cabel or OTG Hub needed) (It works with Micro Usb and Usb Type C devices)

This Project was built to perform an Isochronous Video Stream from all Android Devices (Above 4.0.4 Ice Cream Sandwich)(Mediathek Devices too).

The app connects to USB Cameras via variable, different input values for the camera driver creation. In most cases you won’t need to set up your own camera driver, because other apps may do this for you automatically, but for some Android devices it could help to watch videos from Usb Cameras.

  • LibUsb Support Added: LibUsb raises the performance of the standard Usb Device Driver.

(Some OTG cabels doesn’t work —> I’ll found one which is an extern powered more Port USB-C OTG cable and doesn’t work . ) (An non working OTG cable doesn’t show the right interfaces and endpoints of you camera: —> When you click on ‘List Up The Camera’ Button)

Since Android 9 Google made a mistake granting the Usb Permissions for Usb Cameras, so this app may not works on Android 9 + Devices —> https://issuetracker.google.com/issues/145082934

Explaination: Before you start with entering the Camera values, your Android device have to detect the Camera: So you click the Button and then the Button . The app will ask you for granting the permissions.

In the Picture above a camera was found and the Permissions to the Camera are granted. If no Camera is detected, you can nott use this app. (except of the WebRTC function). Next you have read out the camera Interfaces, to see if your camera is UVC complient. So you click the Button: :

Here you can see a sucessful return of an UVC compliant camera. The first Interface is always the ControlInterface and the second is always the Stream Interface. This Controlinterface (1st) has only 1 Endpoint. The StreamInterface could have more than one Endpoints (depends on the supported resolution of the camera). Here the Endpoint of the StreamInterface has a maxPacketSize of 3072 bytes (You need such a value later). (It could be, that your camera has an audio output, or Sd-Card output too, than see more than 2 Interfaces for your device). If those two Buttons work correctly, you can start to set up the UVC values: Click the Button to start the camera setup. You have two pissibilies: The and the Method. The method is in beta stadium for now, so if this button fails, you choose the method next time! The automatic method should find working camera values for its own, but this values may not be optimal for video transmission. To choose the right values for your own, you click on the Button.

Manual Method Explained: First you choose you Maximal Packet Size: You Camera may supports more Values for the MaxPacketSize, so you can test out each of them, which works best. If your phone uses a Mediathek Chipset you may choose the smallest value, but normaly you choose the highest value! Click on and proceed to the Packets Per Request selection: The Values you select builds the size of the Stream. This means if you select higher Values (such as 32 or more ..) you stream gets bigger, but there may could result error from your device or the camera because of a too large amount of data. For the start you select 1 for this Value. (This would be definitly to less, but you can raise it later) .. Next Sceen shows the ActiveUrbs (actice Usb Request Blocks) —> This is also a value which represents the size of the camera stream. One Block of the activeUrbs is exactly the maxPacketSize x packetsPerRequest. You can select 1 for the start (You will have to raise it later ..) Then the Setup Method will ask you for the Camera Format, which your camera supports. If there is only one format, you click on , if there were more, you select one (does not matter which one) (eventually MJpeg if present) and click on . Next you have to select you Camera Resolution, which you camera supports with the Format (perhaps your camera supports other resolutions, with the other Format . ). Select something . and click on Then you have to select the Frame Interval, which your camera supports. You can click on a Value (maybe the lowest on displayed on the screen, because it is better for the setup. You can save your Entries now: Click on to save this values (you do not need to run the method again, if you have finished the setup and found some working values . If you click on in the next screen —> an automatic name will be taken from the camera to save the file. You can also enter a unique name or enter the value, which is displayed on the bottom, to choose an existing file.

Читайте также:  Вернуть свой андроид смартфон

The picture shows the output of the sucessful setup: Now you want to know, if your Camera works with your selected Values. So you start the comunication with your camera by clicking on the Button and then you select the first entry

If you output is the same like on the Picture above, you have sucessfuly initialized your camera with your selected values. If you do not get a sucessful output of this Button (Video Probe-Commit Control) you can not use the app with your phone / camera. If this output fails, you may contact the developer or try to run the manual Uvc setup method again. If you were sucessful, then you can proceed with reading out the camera frames (first only over the Text View, because your frames may be corrupted or too short or .. To receive some data from your camera, your press the Button again and then on and then on . You then should receive the first frame data from your camera.

The first data which was received on the picture above, were 39950 byte in this case. This means that the camera communicats with the android device and trys to submit the frame data. But the data received above is much to less for a frame Image of a sample size of 640 x 480. So tbe Values «ActiveUrbs» and «PacketsPerRequest» should be raised to get a better output: in my case to 16 Packets and 16 Urbs. If you were not able to get the frame data from your camera, then re-run the manual setup method and change same values. (lower the maxPacketSize, raise activeUrbs, raise packetsPerRequest). To raise the vales for (packetsPerRequest and activeUrbs) you can re-run the setup method or you click on the Button There you should only change the values for these two values (packetsPerRequest and activeUrbs). If you re-run the manual method, you can keep your values by clicking on done, or type in new values to change em.

Here you see, that the frame now gots larger —> 614400 —> this is exact the size of imageWidth x ImageHight x 2 —> 640 x 480 x 2. So in the shown case, the correct setting was found and now the camera setup is finished! Sometimes cameras compresses the frames they send to the devices, so in some cases you have to receive frames with a nearly same size too each other (use the 2nd method from the testrun menu —> «Frames for 5 seconds») When all frames are identically (or nearly) and also all methods above were sucessful, you have sucessfuly finish the setup. You will sure have to spend more time to figure out the right values, but if you have found them, save them and later you can easy restore them any time. If you want to delete some savefiles you will have to manually do this with a file explorer (but only this one you do not need any more) To the Button «Frames for 5 secound»: Have a look at your frames: If they are all identically and big enougth, than you can proceed to start the camera stream with the button from the main screen. Otherwise you have to edit some values for your camera: Perhaps -PacketsPerRequest- or -ActiveUrbs-, or something else. Click the —> Button to start the transmission. If everything works, you can watch the video of your camera.

Descripton of the Camera Values:

Alt-Setting: The Alt-Setting is a camera specific setting which defines which interface of your camera shall be used for the isochronous data transfer.

Maximal-Packet-Size: Each Alt-Setting has its own Maximal-Packet-Size. The Maximal-Packet-Size is byte Number which defines how many bytes each Packet of the iso transfer maximal contains.

Format-Index: Your Camera can support different Format Indexs. This could be MJPEG, or uncompressed (YUV) or .

Videoformat: This is a helper value, which has to be set to your selected Format-Index. You have to enter YUV, or MJPEG, or .

Frame-Index: Each Format-Index of your camera can have different Frame Indexs. This is a number which represents the camera resolution (1920×1020, or 640×480)

Image-Width, Image-Hight: This are helper values, which have to be set to your selected Frame-Index. For Example: Image-Width = 640 and Image-Hight = 480

Frame-Interval: The Frame-Interval is a number which defines, on how much nano secounds each new frame will be sent from the camera to your device.For example: 666666 means each 0,066 Secounds a frame is sent. 666666 = 15 frames per secound.333333 are 30 Frames per secound

Packets-Per-Request: This is a value wich defines how many Packet will be sent from your camera to your device in one cycle of the transfer.

Active-Urbs: And this value defines have many cycles are running paralell to each other in the data steam between camera and Android device.

Источник

Оцените статью