Кодирование и потоковое видео в реальном времени на веб-странице
Я пытаюсь показать прямую трансляцию видео с веб-камеры на веб-странице, и у меня есть рабочий проект. Тем не менее, я не удовлетворен работой и ищу лучший способ сделать работу.
У меня есть веб-камера, подключенная к Raspberry PI, и веб-сервер, который является простым сервером Python-Flask. Изображения с веб-камеры захватываются с помощью OpenCV и форматируются в формате JPEG. Позднее эти JPEG-файлы отправляются на один из UDP-портов сервера. До этого момента я делал что-то вроде домашней потоковой передачи MJPEG(motion-jpeg).
На стороне сервера у меня есть простой скрипт на python, который непрерывно читает порт UDP и помещает изображение JPEG в холст HTML5. Это достаточно быстро, чтобы создать ощущение живого потока.
Проблемы:
Это сжимает видео очень мало. На самом деле это не сжимает видео. Это только уменьшает размер кадра, форматируя как JPEG.
FPS низкий, а также качество потока не очень хорошее.
Пока это не главное, но UDP не является безопасным способом потоковой передачи видео.
Сервер занят выбором изображений из UDP. Нужен многопоточный серверный дизайн.
Альтернативы:
- Я использовал FFMPEG прежде, чтобы преобразовать видео форматы и также передать предварительно записанное видео. Я предполагаю, что можно кодировать (скажем, H.264) и транслировать живое видео с веб-камеры, используя ffmpeg или avconv. (Кодирование)
Это применимо к Raspberry PI?
- VLC может воспроизводить потоковое видео в сети. (Поток)
Есть ли Media Player для встраивания в HTML/Javascript для обработки сетевого потока, как это делает VLC?
- Я читал о HLS (HTTP Live Stream) и MPEG-DASH.
Это относится к этому случаю? Если это так, как я должен их использовать?
Есть ли другой способ показать прямой эфир на веб-странице?
- RTSP - это безопасный протокол.
Какова наилучшая практика для протокола транспортного уровня при потоковой передаче видео?
2 ответа
Я постараюсь ответить на как можно больше ваших перечисленных "проблем":
FPS низкий, а также качество потока не очень хорошее.
Поскольку вы используете Flask, вы можете использовать очень мощный url_for
ключевое слово для отображения ваших потоковых кадров непосредственно в тег img. Вот как вы можете добиться этого:
На веб-странице добавьте <img src="{{url_for('video_feed')}}"
где вы хотите, чтобы ваш канал транслировался.
На сервере сделайте следующее:
def gen(camera):
frame = camera.read()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
@app.route('/video_feed')
def video_feed():
return Response(gen(), mimetype='multipart/x-mixed-replace; boundary=frame')
Теперь тег img будет отображать изображение, присутствующее в конечной точке video_feed
который имеет тип multipart. Следовательно, он будет продолжать запрашивать новые детали (новые рамы) в вашем случае.
Я нашел этот подход довольно быстрым!
Кредиты: сообщение в блоге Мигеля Гринберга
Пока это не главное, но UDP не является безопасным способом потоковой передачи видео.
Большинство потоковых видеоустройств не шифруют потоковое видео, потому что это требует больших вычислительных затрат. Поэтому, хотя вы можете подключаться к встроенному веб-серверу на устройстве через HTTPS и, возможно, вам придется войти в устройство, чтобы управлять им, вся эта безопасность ограничена "плоскостью управления". Само видео почти наверняка будет передаваться в незашифрованном виде., Если он соответствует открытому стандарту, он, вероятно, отправляется через RTP/RTSP или через HTTP Live Streaming (HLS).
Источник: Мысли о потоковой передаче видео безопасно
Сервер занят выбором изображений из UDP. Нужен многопоточный серверный дизайн.
Используя вышеуказанный подход, я смог взаимодействовать с сервером даже во время потоковой передачи видео. С веб-сервером разработки Flask вы можете добавить threaded=True
на ваш app.run()
позвонить или --with-threads
если вы используете Flask CLI.
Вы также можете использовать Gunicorn в сочетании с gevent или eventlet для дальнейшего контроля над вашими потоками.
Вы можете использовать FFmpeg для мультиплексирования видеопотока в H.264 в контейнере mp4, а затем это можно напрямую использовать в элементе видео HTML5.