diff --git a/cmd/camera-streamer/http.c b/cmd/camera-streamer/http.c new file mode 100644 index 0000000..8e2b171 --- /dev/null +++ b/cmd/camera-streamer/http.c @@ -0,0 +1,87 @@ +#include "http/http.h" +#include "opts/opts.h" +#include "opts/log.h" +#include "opts/fourcc.h" +#include "device/camera/camera.h" +#include "rtsp/rtsp.h" + +extern unsigned char html_index_html[]; +extern unsigned int html_index_html_len; +extern unsigned char html_video_html[]; +extern unsigned int html_video_html_len; +extern unsigned char html_jmuxer_min_js[]; +extern unsigned int html_jmuxer_min_js_len; +extern camera_t *camera; + +void *camera_http_set_option(http_worker_t *worker, FILE *stream, const char *key, const char *value, void *headersp) +{ + bool *headers = headersp; + + if (!camera) { + if (!*headers) { + http_500(stream, ""); + *headers = true; + } + fprintf(stream, "No camera attached.\r\n"); + return NULL; + } + + bool set = false; + + for (int i = 0; i < MAX_DEVICES; i++) { + if (device_set_option_string(camera->devices[i], key, value) == 0) { + set = true; + break; + } + } + + if (set) { + if (!*headers) { + http_200(stream, ""); + *headers = true; + } + fprintf(stream, "The '%s' was set to '%s'.\r\n", key, value); + } else { + if (!*headers) { + http_500(stream, ""); + *headers = true; + } + fprintf(stream, "Cannot set '%s' to '%s'.\r\n", key, value); + } + + return NULL; +} + +void camera_http_option(http_worker_t *worker, FILE *stream) +{ + bool headers = false; + http_enum_params(worker, stream, camera_http_set_option, &headers); + if (!headers) { + http_404(stream, ""); + fprintf(stream, "No options passed.\r\n"); + } + + fprintf(stream, "\r\nSet: /option?name=value\r\n\r\n"); + + if (camera) { + for (int i = 0; i < MAX_DEVICES; i++) { + device_dump_options(camera->devices[i], stream); + } + } +} + +http_method_t http_methods[] = { + { "GET /snapshot?", http_snapshot }, + { "GET /snapshot.jpg?", http_snapshot }, + { "GET /stream?", http_stream }, + { "GET /?action=snapshot", http_snapshot }, + { "GET /?action=stream", http_stream }, + { "GET /video?", http_content, "text/html", html_video_html, 0, &html_video_html_len }, + { "GET /video.h264?", http_h264_video }, + { "GET /video.mkv?", http_mkv_video }, + { "GET /video.mp4?", http_mp4_video }, + { "GET /option?", camera_http_option }, + { "GET /jmuxer.min.js?", http_content, "text/javascript", html_jmuxer_min_js, 0, &html_jmuxer_min_js_len }, + { "GET /?", http_content, "text/html", html_index_html, 0, &html_index_html_len }, + { } +}; diff --git a/cmd/camera-streamer/main.c b/cmd/camera-streamer/main.c new file mode 100644 index 0000000..dc4450f --- /dev/null +++ b/cmd/camera-streamer/main.c @@ -0,0 +1,66 @@ +#include "http/http.h" +#include "opts/opts.h" +#include "opts/log.h" +#include "opts/fourcc.h" +#include "device/camera/camera.h" +#include "rtsp/rtsp.h" + +#include +#include + +extern option_t all_options[]; +extern camera_options_t camera_options; +extern http_server_options_t http_options; +extern http_method_t http_methods[]; + +camera_t *camera; + +int main(int argc, char *argv[]) +{ + int http_fd = -1; + int ret = -1; + + if (parse_opts(all_options, argc, argv) < 0) { + return -1; + } + + if (camera_options.list_options) { + camera = camera_open(&camera_options); + if (camera) { + printf("\n"); + for (int i = 0; i < MAX_DEVICES; i++) { + device_dump_options(camera->devices[i], stdout); + } + camera_close(&camera); + } + return -1; + } + + http_fd = http_server(&http_options, http_methods); + if (http_fd < 0) { + goto error; + } + + if (rtsp_options.port > 0 && rtsp_server() < 0) { + goto error; + } + + while (true) { + camera = camera_open(&camera_options); + if (camera) { + ret = camera_run(camera); + camera_close(&camera); + } + + if (camera_options.auto_reconnect > 0) { + LOG_INFO(NULL, "Automatically reconnecting in %d seconds...", camera_options.auto_reconnect); + sleep(camera_options.auto_reconnect); + } else { + break; + } + } + +error: + close(http_fd); + return ret; +} diff --git a/cmd/camera-streamer/camera-streamer.c b/cmd/camera-streamer/opts.c similarity index 56% rename from cmd/camera-streamer/camera-streamer.c rename to cmd/camera-streamer/opts.c index 61e470a..2664956 100644 --- a/cmd/camera-streamer/camera-streamer.c +++ b/cmd/camera-streamer/opts.c @@ -5,91 +5,6 @@ #include "device/camera/camera.h" #include "rtsp/rtsp.h" -#include -#include - -extern unsigned char html_index_html[]; -extern unsigned int html_index_html_len; -extern unsigned char html_video_html[]; -extern unsigned int html_video_html_len; -extern unsigned char html_jmuxer_min_js[]; -extern unsigned int html_jmuxer_min_js_len; - -camera_t *camera; - -void *camera_http_set_option(http_worker_t *worker, FILE *stream, const char *key, const char *value, void *headersp) -{ - bool *headers = headersp; - - if (!camera) { - if (!*headers) { - http_500(stream, ""); - *headers = true; - } - fprintf(stream, "No camera attached.\r\n"); - return NULL; - } - - bool set = false; - - for (int i = 0; i < MAX_DEVICES; i++) { - if (device_set_option_string(camera->devices[i], key, value) == 0) { - set = true; - break; - } - } - - if (set) { - if (!*headers) { - http_200(stream, ""); - *headers = true; - } - fprintf(stream, "The '%s' was set to '%s'.\r\n", key, value); - } else { - if (!*headers) { - http_500(stream, ""); - *headers = true; - } - fprintf(stream, "Cannot set '%s' to '%s'.\r\n", key, value); - } - - return NULL; -} - -void camera_http_option(http_worker_t *worker, FILE *stream) -{ - bool headers = false; - http_enum_params(worker, stream, camera_http_set_option, &headers); - if (!headers) { - http_404(stream, ""); - fprintf(stream, "No options passed.\r\n"); - } - - fprintf(stream, "\r\nSet: /option?name=value\r\n\r\n"); - - if (camera) { - for (int i = 0; i < MAX_DEVICES; i++) { - device_dump_options(camera->devices[i], stream); - } - } -} - -http_method_t http_methods[] = { - { "GET /snapshot?", http_snapshot }, - { "GET /snapshot.jpg?", http_snapshot }, - { "GET /stream?", http_stream }, - { "GET /?action=snapshot", http_snapshot }, - { "GET /?action=stream", http_stream }, - { "GET /video?", http_content, "text/html", html_video_html, 0, &html_video_html_len }, - { "GET /video.h264?", http_h264_video }, - { "GET /video.mkv?", http_mkv_video }, - { "GET /video.mp4?", http_mp4_video }, - { "GET /option?", camera_http_option }, - { "GET /jmuxer.min.js?", http_content, "text/javascript", html_jmuxer_min_js, 0, &html_jmuxer_min_js_len }, - { "GET /?", http_content, "text/html", html_index_html, 0, &html_index_html_len }, - { } -}; - camera_options_t camera_options = { .path = "", .width = 1920, @@ -192,54 +107,4 @@ option_t all_options[] = { DEFINE_OPTION_PTR(log, filter, list, "Enable debug logging from the given files. Ex.: `-log-filter=buffer.cc`"), {} -}; - -int main(int argc, char *argv[]) -{ - int http_fd = -1; - int ret = -1; - - if (parse_opts(all_options, argc, argv) < 0) { - return -1; - } - - if (camera_options.list_options) { - camera = camera_open(&camera_options); - if (camera) { - printf("\n"); - for (int i = 0; i < MAX_DEVICES; i++) { - device_dump_options(camera->devices[i], stdout); - } - camera_close(&camera); - } - return -1; - } - - http_fd = http_server(&http_options, http_methods); - if (http_fd < 0) { - goto error; - } - - if (rtsp_options.port > 0 && rtsp_server() < 0) { - goto error; - } - - while (true) { - camera = camera_open(&camera_options); - if (camera) { - ret = camera_run(camera); - camera_close(&camera); - } - - if (camera_options.auto_reconnect > 0) { - LOG_INFO(NULL, "Automatically reconnecting in %d seconds...", camera_options.auto_reconnect); - sleep(camera_options.auto_reconnect); - } else { - break; - } - } - -error: - close(http_fd); - return ret; -} +}; \ No newline at end of file