Add /video to automatically give HLS to supported browser

This commit is contained in:
Kamil Trzcinski
2022-09-06 23:04:55 +02:00
parent 5ee0bee59f
commit 5801152b03
12 changed files with 93 additions and 12 deletions

View File

@ -137,6 +137,7 @@ static void http_ffmpeg_video(http_worker_t *worker, FILE *stream, const char *c
int n = buffer_lock_write_loop(
http_h264_buffer_for_res(worker),
0,
0,
(buffer_write_fn)http_ffmpeg_video_buf_part,
&status);
ffmpeg_remuxer_close(&remuxer);

View File

@ -81,7 +81,7 @@ void http_h264_video(http_worker_t *worker, FILE *stream)
{
http_video_status_t status = { stream };
int n = buffer_lock_write_loop(http_h264_buffer_for_res(worker), 0, (buffer_write_fn)http_video_buf_part, &status);
int n = buffer_lock_write_loop(http_h264_buffer_for_res(worker), 0, 0, (buffer_write_fn)http_video_buf_part, &status);
if (status.wrote_header) {
return;

46
output/http_hls.c Normal file
View File

@ -0,0 +1,46 @@
#include <stdio.h>
#include <stdlib.h>
#include "output.h"
#include "util/opts/log.h"
#include "util/http/http.h"
#include "device/buffer.h"
#include "device/buffer_lock.h"
#include "device/buffer_list.h"
#include "device/device.h"
static const char *const CONTENT_TYPE = "application/x-mpegURL";
static const char *const STREAM_M3U8 =
"#EXTM3U\r\n" \
"#EXT-X-TARGETDURATION:1\r\n" \
"#EXT-X-VERSION:4\r\n" \
"#EXTINF:1.0,\r\n" \
"video.mp4?ts=%zu\r\n";
static const char *const LOCATION_REDIRECT =
"HTTP/1.0 307 Temporary Redirect\r\n"
"Access-Control-Allow-Origin: *\r\n"
"Connection: close\r\n"
"Location: %s\r\n"
"\r\n";
void http_m3u8_video(struct http_worker_s *worker, FILE *stream)
{
uint64_t ts = get_monotonic_time_us(NULL, NULL) / 1000 / 1000;
http_write_responsef(stream, "200 OK", CONTENT_TYPE, STREAM_M3U8, ts);
}
void http_detect_video(struct http_worker_s *worker, FILE *stream)
{
if (strstr(worker->user_agent, "Safari/") && !strstr(worker->user_agent, "Chrome/") && !strstr(worker->user_agent, "Chromium/")) {
// Safari only supports m3u8
fprintf(stream, LOCATION_REDIRECT, "video.m3u8");
} else if (strstr(worker->user_agent, "Firefox/")) {
// Firefox only supports mp4
fprintf(stream, LOCATION_REDIRECT, "video.mp4");
} else {
// Chrome offers best latency with mkv
fprintf(stream, LOCATION_REDIRECT, "video.mkv");
}
}

View File

@ -40,7 +40,7 @@ int http_snapshot_buf_part(buffer_lock_t *buf_lock, buffer_t *buf, int frame, FI
void http_snapshot(http_worker_t *worker, FILE *stream)
{
int n = buffer_lock_write_loop(http_jpeg_buffer_for_res(worker), 1, (buffer_write_fn)http_snapshot_buf_part, stream);
int n = buffer_lock_write_loop(http_jpeg_buffer_for_res(worker), 1, 0, (buffer_write_fn)http_snapshot_buf_part, stream);
if (n <= 0) {
http_500(stream, NULL);
@ -68,7 +68,7 @@ int http_stream_buf_part(buffer_lock_t *buf_lock, buffer_t *buf, int frame, FILE
void http_stream(http_worker_t *worker, FILE *stream)
{
int n = buffer_lock_write_loop(http_jpeg_buffer_for_res(worker), 0, (buffer_write_fn)http_stream_buf_part, stream);
int n = buffer_lock_write_loop(http_jpeg_buffer_for_res(worker), 0, 0, (buffer_write_fn)http_stream_buf_part, stream);
if (n == 0) {
http_500(stream, NULL);

View File

@ -23,4 +23,8 @@ void http_mkv_video(struct http_worker_s *worker, FILE *stream);
void http_mp4_video(struct http_worker_s *worker, FILE *stream);
void http_mov_video(struct http_worker_s *worker, FILE *stream);
// HLS
void http_m3u8_video(struct http_worker_s *worker, FILE *stream);
void http_detect_video(struct http_worker_s *worker, FILE *stream);
#define HTTP_LOW_RES_PARAM "res=low"