diff --git a/debian/control.in b/debian/control.in index 78983b05..2df4d69a 100644 --- a/debian/control.in +++ b/debian/control.in @@ -27,6 +27,7 @@ Depends: ${shlibs:Depends}, ssl-cert, ucf, curl, sysstat, vainfo, i965-va-driver, cron, + certbot, # python3-pip, #focal php-sqlite3, php-gd, php-curl, php-mysql #jammy php-sqlite3, php-gd, php-curl, php-mysql diff --git a/installer/v3.sh b/installer/v3.sh index 73ed763d..423a7313 100644 --- a/installer/v3.sh +++ b/installer/v3.sh @@ -91,6 +91,29 @@ jammy_install() systemctl restart bluecherry } +# Ubuntu 23.10 +mantic_install() +{ + # Differences from jammy: + # Don't add ppa:ondrej/php, it fails for Mantic. + # Don't explicitly state which php packages to install + apt-get update + apt -y install gpg software-properties-common wget + wget -q https://dl.bluecherrydvr.com/key/bluecherry.asc -O- | sudo tee /etc/apt/trusted.gpg.d/bluecherry.asc + VERSION_CODENAME=mantic + : "${SRCLIST_URL:=https://dl.bluecherrydvr.com/sources.list.d/bluecherry-"$VERSION_CODENAME"-unstable.list}" + wget --output-document=/etc/apt/sources.list.d/bluecherry-"$VERSION_CODENAME".list "$SRCLIST_URL" + apt -y update + apt -y install bluecherry + systemctl restart bluecherry +} + +# Ubuntu 24.04 +noble_install() +{ + jammy_install +} + centos_7_install() { setenforce 0 @@ -132,6 +155,12 @@ bullseye_install() apt-get -y install mariadb-server bluecherry } +# Debian 12 +bookworm_install() +{ + bullseye_install +} + check_distro() { if [[ -e /etc/lsb-release ]] @@ -165,9 +194,14 @@ if [[ "$ID" == "ubuntu" && "$VERSION_ID" == "18.04" && "$VERSION_CODENAME" == elif [[ "$ID" == "ubuntu" && "$VERSION_ID" == "20.10" && "$VERSION_CODENAME" == "groovy" ]]; then groovy_install; elif [[ "$ID" == "ubuntu" && "$VERSION_ID" == "20.04" && "$VERSION_CODENAME" == "focal" ]]; then focal_install; elif [[ "$ID" == "ubuntu" && "$VERSION_ID" == "22.04" && "$VERSION_CODENAME" == "jammy" ]]; then jammy_install; +elif [[ "$ID" == "ubuntu" && "$VERSION_ID" == "23.10" && "$VERSION_CODENAME" == "mantic" ]]; then mantic_install; +elif [[ "$ID" == "ubuntu" && "$VERSION_ID" == "24.04" && "$VERSION_CODENAME" == "noble" ]]; then noble_install; elif [[ "$ID" == "debian" && "$VERSION_ID" == "10" && "$VERSION_CODENAME" == "buster" ]]; then buster_install; elif [[ "$ID" == "debian" && "$VERSION_ID" == "11" && "$VERSION_CODENAME" == "bullseye" ]]; then bullseye_install; -elif [[ "$ID" == "mint" && "$VERSION_ID" == "21.1" && "$VERSION_CODENAME" == "vera" ]]; then jammy_install; # Mint 21.1 Vera, based on Ubuntu 22.04 Jammy +elif [[ "$ID" == "debian" && "$VERSION_ID" == "12" && "$VERSION_CODENAME" == "bookworm" ]]; then bookworm_install; +elif [[ "$ID" == "linuxmint" && "$VERSION_ID" == "21.1" && "$VERSION_CODENAME" == "vera" ]]; then jammy_install; # Mint 21.1 Vera, based on Ubuntu 22.04 Jammy +elif [[ "$ID" == "linuxmint" && "$VERSION_ID" == "21.2" && "$VERSION_CODENAME" == "victoria" ]]; then jammy_install; # based on Ubuntu 22.04 Jammy +elif [[ "$ID" == "linuxmint" && "$VERSION_ID" == "21.3" && "$VERSION_CODENAME" == "virginia" ]]; then jammy_install; # based on Ubuntu 22.04 Jammy else - echo "Currently we only support Ubuntu 18.04 (Bionic), Ubuntu 20.04 (Focal), Ubuntu 22.04 (Jammy) and Debian 10 (Buster), Linux Mint 21.1 (Vera) for unstable testing" + echo "Currently we only support Ubuntu 18.04 (Bionic), Ubuntu 20.04 (Focal), Ubuntu 22.04 (Jammy), Ubuntu 23.10 (Mantic), Ubuntu 24.04 (Noble) and Debian 10 (Buster), 11 (Bullseye), 12 (Bookworm), Linux Mint 21.1 (Vera), 21.2 (Victoria), 21.3 (Virginia) for unstable testing" fi diff --git a/lib/lavf_device.cpp b/lib/lavf_device.cpp index 324ea465..d32afab5 100644 --- a/lib/lavf_device.cpp +++ b/lib/lavf_device.cpp @@ -77,7 +77,7 @@ int lavf_device::start() if (ctx) return 0; AVDictionary *avopt_open_input = NULL; - AVInputFormat *input_fmt = NULL; + const AVInputFormat *input_fmt = NULL; bc_log(Debug, "Opening session from URL: %s", url); diff --git a/lib/v4l2_device_solo6x10.cpp b/lib/v4l2_device_solo6x10.cpp index 83bc4354..5281b896 100644 --- a/lib/v4l2_device_solo6x10.cpp +++ b/lib/v4l2_device_solo6x10.cpp @@ -235,7 +235,7 @@ int v4l2_device_solo6x10::start() av_dict_set(&open_opts, "input_format", fmtname, 0); av_dict_set(&open_opts, "format_whitelist", "v4l2", 0); - AVInputFormat *input_fmt = av_find_input_format("v4l2"); + const AVInputFormat *input_fmt = av_find_input_format("v4l2"); if (!input_fmt) { bc_log(Error, "v4l2 input format not found"); return -1; diff --git a/lib/v4l2_device_tw5864.cpp b/lib/v4l2_device_tw5864.cpp index 18704ebf..25bbfb35 100644 --- a/lib/v4l2_device_tw5864.cpp +++ b/lib/v4l2_device_tw5864.cpp @@ -242,7 +242,7 @@ int v4l2_device_tw5864::start() av_dict_set(&open_opts, "input_format", "h264", 0); av_dict_set(&open_opts, "format_whitelist", "v4l2", 0); - AVInputFormat *input_fmt = av_find_input_format("v4l2"); + const AVInputFormat *input_fmt = av_find_input_format("v4l2"); if (!input_fmt) { bc_log(Error, "v4l2 input format not found"); return -1; diff --git a/misc/BCMK b/misc/BCMK index 89edf40e..89066380 100644 --- a/misc/BCMK +++ b/misc/BCMK @@ -63,6 +63,7 @@ libav/config.mak: --enable-protocol=pipe \ --enable-protocol=http \ --enable-protocol=https \ + --enable-protocol=tls \ \ --enable-muxer=matroska \ --enable-muxer=mjpeg \ diff --git a/misc/libav b/misc/libav index 1529dfb7..e38092ef 160000 --- a/misc/libav +++ b/misc/libav @@ -1 +1 @@ -Subproject commit 1529dfb73a5157dcb8762051ec4c8d8341762478 +Subproject commit e38092ef9395d7049f871ef4d5411eb410e283e0 diff --git a/misc/postinstall.sh b/misc/postinstall.sh index 76067395..87c7a1e5 100755 --- a/misc/postinstall.sh +++ b/misc/postinstall.sh @@ -81,15 +81,45 @@ function stop_nginx function install_pip { + # If already installed - nothing to do + if which pip3 >/dev/null; then + return + fi -if [[ $(cat /etc/os-release | grep "UBUNTU" | grep bionic) ]] - then + source /etc/os-release + if [[ "$ID" == ubuntu ]] && [[ "$VERSION_CODENAME" == bionic ]]; then wget --output-document=/tmp/get-pip.py https://bootstrap.pypa.io/pip/3.6/get-pip.py + python3 /tmp/get-pip.py else wget --output-document=/tmp/get-pip.py https://bootstrap.pypa.io/get-pip.py -fi - python3 /tmp/get-pip.py + python3 /tmp/get-pip.py + fi +} + +function install_certbot +{ + source /etc/os-release + if [[ "$ID" == ubuntu ]] && [[ "$VERSION_CODENAME" == noble ]]; then + echo 'For Ubuntu 24.04 (noble) we rely on packaged certbot' + return + elif [[ "$ID" == ubuntu ]] && [[ "$VERSION_CODENAME" == mantic ]]; then + echo 'For Ubuntu 23.10 (mantic) we rely on packaged certbot' + return + elif [[ "$ID" == debian ]] && [[ "$VERSION_CODENAME" == bookworm ]]; then + echo 'For Debian 12 (bookworm) we rely on packaged certbot' + return + fi + + export PATH=/usr/local/bin:"$PATH" + # Ubuntu 23+, Debian 12 make this step fail. Fall back to system package. + install_pip || return + + # Install pip3 dependencies + pip3 install --user --upgrade setuptools_rust certbot certbot-dns-subdomain-provider + pip3 install --user --upgrade pip || true + pip3 install --user --upgrade cryptography + pip3 install pyopenssl --upgrade } function start_apache @@ -407,16 +437,13 @@ case "$1" in if test -f "/usr/share/bluecherry/nginx-includes/subdomain.conf"; then sed -i 's/snakeoil.conf/subdomain.conf/g' /etc/nginx/sites-enabled/bluecherry.conf fi - -# Install pip from bootstrap - install_pip + # Debian 10 lacks version-agnostic link for php-fpm.sock. Add it in a compatible way. + if ! [[ -L /run/php/php-fpm.sock ]]; then + update-alternatives --install /run/php/php-fpm.sock php-fpm.sock /run/php/php*.*-fpm.sock 0 + fi - # Install pip3 dependencies - /usr/local/bin/pip3 install --user --upgrade setuptools_rust certbot certbot-dns-subdomain-provider - /usr/local/bin/pip3 install --user --upgrade pip - /usr/local/bin/pip3 install --user --upgrade cryptography - /usr/local/bin/pip3 install pyopenssl --upgrade + install_certbot # Install crontabs for subdomain renewal and SSL renewal using certbot crontab -l 2>/dev/null || true; printf "* * */5 * * certbot renew --config-dir=/usr/share/bluecherry/nginx-includes/letsencrypt/ >/dev/null 2>&1\n*/5 * * * * curl -k https://localhost:7001/subdomainprovidercron >/dev/null 2>&1\n" | crontab - diff --git a/nginx-configs/bluecherry.conf b/nginx-configs/bluecherry.conf index 1a6c4138..f4e303cb 100644 --- a/nginx-configs/bluecherry.conf +++ b/nginx-configs/bluecherry.conf @@ -9,7 +9,7 @@ server { access_log /var/log/nginx/bluecherry-access.log; include /usr/share/bluecherry/nginx-includes/snakeoil.conf; - include /usr/share/bluecherry/nginx-includes/__BLUECHERRY_DIST_CODENAME__.conf; + include /usr/share/bluecherry/nginx-includes/php-generic.conf; # this is required for letsencrypt www challange location /.well-known/ { diff --git a/nginx-configs/php/bionic.conf b/nginx-configs/php/bionic.conf index ae03b5dd..3029440e 100644 --- a/nginx-configs/php/bionic.conf +++ b/nginx-configs/php/bionic.conf @@ -1,3 +1,4 @@ +# Deprecated - use php-generic.conf location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; @@ -7,4 +8,4 @@ fastcgi_param PATH_INFO $path_info; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_index index.php; - } \ No newline at end of file + } diff --git a/nginx-configs/php/bookworm.conf b/nginx-configs/php/bookworm.conf new file mode 100644 index 00000000..24deb449 --- /dev/null +++ b/nginx-configs/php/bookworm.conf @@ -0,0 +1,11 @@ +# Deprecated - use php-generic.conf + location ~ \.php$ { + fastcgi_pass unix:/run/php/php8.2-fpm.sock; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi.conf; + set $path_info $fastcgi_path_info; + fastcgi_read_timeout 300; + fastcgi_param PATH_INFO $path_info; + fastcgi_param SCRIPT_FILENAME $document_root/index.php; + fastcgi_index index.php; + } diff --git a/nginx-configs/php/bullseye.conf b/nginx-configs/php/bullseye.conf index 1ea15ef3..94faf9e5 100644 --- a/nginx-configs/php/bullseye.conf +++ b/nginx-configs/php/bullseye.conf @@ -1,3 +1,4 @@ +# Deprecated - use php-generic.conf location ~ \.php$ { fastcgi_pass unix:/run/php/php7.4-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; diff --git a/nginx-configs/php/buster.conf b/nginx-configs/php/buster.conf index b44e87fc..64a98af1 100644 --- a/nginx-configs/php/buster.conf +++ b/nginx-configs/php/buster.conf @@ -1,3 +1,4 @@ +# Deprecated - use php-generic.conf location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; diff --git a/nginx-configs/php/focal.conf b/nginx-configs/php/focal.conf index 2097e86a..8ef6069a 100644 --- a/nginx-configs/php/focal.conf +++ b/nginx-configs/php/focal.conf @@ -1,3 +1,4 @@ +# Deprecated - use php-generic.conf location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; diff --git a/nginx-configs/php/groovy.conf b/nginx-configs/php/groovy.conf index 2097e86a..8ef6069a 100644 --- a/nginx-configs/php/groovy.conf +++ b/nginx-configs/php/groovy.conf @@ -1,3 +1,4 @@ +# Deprecated - use php-generic.conf location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; diff --git a/nginx-configs/php/hirsute.conf b/nginx-configs/php/hirsute.conf index 2097e86a..8ef6069a 100644 --- a/nginx-configs/php/hirsute.conf +++ b/nginx-configs/php/hirsute.conf @@ -1,3 +1,4 @@ +# Deprecated - use php-generic.conf location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; diff --git a/nginx-configs/php/jammy.conf b/nginx-configs/php/jammy.conf index 2097e86a..8ef6069a 100644 --- a/nginx-configs/php/jammy.conf +++ b/nginx-configs/php/jammy.conf @@ -1,3 +1,4 @@ +# Deprecated - use php-generic.conf location ~ \.php$ { fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; diff --git a/nginx-configs/php/noble.conf b/nginx-configs/php/noble.conf new file mode 120000 index 00000000..45baf05a --- /dev/null +++ b/nginx-configs/php/noble.conf @@ -0,0 +1 @@ +bookworm.conf \ No newline at end of file diff --git a/nginx-configs/php/php-generic.conf b/nginx-configs/php/php-generic.conf new file mode 100644 index 00000000..8d0fdf7b --- /dev/null +++ b/nginx-configs/php/php-generic.conf @@ -0,0 +1,11 @@ + location ~ \.php$ { + # Debian 10 php-fpm doesn't maintain /run/php/php-fpm.sock + fastcgi_pass unix:/etc/alternatives/php-fpm.sock; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi.conf; + set $path_info $fastcgi_path_info; + fastcgi_read_timeout 300; + fastcgi_param PATH_INFO $path_info; + fastcgi_param SCRIPT_FILENAME $document_root/index.php; + fastcgi_index index.php; + } diff --git a/nginx-configs/snakeoil.conf b/nginx-configs/snakeoil.conf new file mode 100644 index 00000000..d2366415 --- /dev/null +++ b/nginx-configs/snakeoil.conf @@ -0,0 +1,2 @@ +ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem; +ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key; diff --git a/scripts/build_helper/post_make_install.sh b/scripts/build_helper/post_make_install.sh index 8c2a950a..add334ae 100755 --- a/scripts/build_helper/post_make_install.sh +++ b/scripts/build_helper/post_make_install.sh @@ -50,6 +50,7 @@ then mkdir -p ${DST_DIR}/usr/share/bluecherry/nginx-includes/ cp ${SRC_PATH}/nginx-configs/php/* ${DST_DIR}/usr/share/bluecherry/nginx-includes/ + cp ${SRC_PATH}/nginx-configs/snakeoil.conf ${DST_DIR}/usr/share/bluecherry/nginx-includes/ if [[ $(cat /etc/os-release | grep "^ID=" | grep debian) ]] then @@ -60,38 +61,11 @@ then mkdir -p ${DST_DIR}/etc/nginx/sites-enabled/ + # This handling is probably because of snakeoil.conf/subdomain.conf dynamicity if test -f /etc/nginx/sites-enabled/bluecherry.conf; then cp /etc/nginx/sites-enabled/bluecherry.conf \ ${DST_DIR}/etc/nginx/sites-enabled/ else - cat ${SRC_PATH}/nginx-configs/bluecherry.conf | sed \ - -e "s/__BLUECHERRY_DIST_CODENAME__/$_CODENAME_/" \ - > ${DST_DIR}/etc/nginx/sites-enabled/bluecherry.conf + cp ${SRC_PATH}/nginx-configs/bluecherry.conf ${DST_DIR}/etc/nginx/sites-enabled/bluecherry.conf fi - - touch ${DST_DIR}/usr/share/bluecherry/nginx-includes/snakeoil.conf - echo "ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;" >> ${DST_DIR}/usr/share/bluecherry/nginx-includes/snakeoil.conf - echo "ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;" >> ${DST_DIR}/usr/share/bluecherry/nginx-includes/snakeoil.conf fi - -# Apache configurations are no more required -#if [[ ${PKG_TYPE} == "deb" ]] -#then -# install -d ${DST_DIR}/etc/apache2/sites-available -# cat ${SRC_PATH}/debian/apache.conf | sed \ -# -e "s/__BLUECHERRY_APACHE_ERROR_LOG__/\/var\/log\/apache2\/bluecherry-error.log/" \ -# -e "s/__BLUECHERRY_APACHE_ACCESS_LOG__/\/var\/log\/apache2\/bluecherry-access.log/" \ -# -e "s/__BLUECHERRY_APACHE_CERTIFICATE_FILE__/\/etc\/ssl\/certs\/ssl-cert-snakeoil.pem/" \ -# -e "s/__BLUECHERRY_APACHE_CERTIFICATE_KEY_FILE__/\/etc\/ssl\/private\/ssl-cert-snakeoil.key/" \ -# > ${DST_DIR}/etc/apache2/sites-available/bluecherry.conf -#else -# install -d ${DST_DIR}/etc/httpd/sites-available -# cat ${SRC_PATH}/debian/apache.conf | sed \ -# -e "s/__BLUECHERRY_APACHE_ERROR_LOG__/\/var\/log\/httpd\/bluecherry_error_log/" \ -# -e "s/__BLUECHERRY_APACHE_ACCESS_LOG__/\/var\/log\/httpd\/bluecherry_access_log/" \ -# -e "s/__BLUECHERRY_APACHE_CERTIFICATE_FILE__/\/etc\/pki\/tls\/certs\/localhost.crt/" \ -# -e "s/__BLUECHERRY_APACHE_CERTIFICATE_KEY_FILE__/\/etc\/pki\/tls\/private\/localhost.key/" \ -# > ${DST_DIR}/etc/httpd/sites-available/bluecherry.conf -#fi -# install -m644${DST_DIR}.apparmor \ -# ${DST_DIR}/etc/apparmor.d/usr.sbin.bc-server diff --git a/server/ffmpeg-init.c b/server/ffmpeg-init.c index 1a0e4440..ab634020 100644 --- a/server/ffmpeg-init.c +++ b/server/ffmpeg-init.c @@ -25,48 +25,6 @@ #include #include "logc.h" -/* Fake H.264 encoder for libavcodec. We're only muxing video, never reencoding, - * so a real encoder isn't neeeded, but one must be present for the process to - * succeed. ffmpeg does not support h264 encoding without libx264, which is GPL. - */ -static int fake_h264_init(AVCodecContext *ctx) -{ - (void)ctx; - return 0; -} - -static int fake_h264_close(AVCodecContext *ctx) -{ - (void)ctx; - return 0; -} - -static int fake_h264_frame(AVCodecContext *ctx, AVPacket *avpkt, - const AVFrame *frame, int *got_packet_ptr) -{ - (void)ctx; - (void)avpkt; - (void)frame; - (void)got_packet_ptr; - return -1; -} - -static AVCodec fake_h264_encoder = { - .name = "fakeh264", - .long_name = "Fake H.264 Encoder for RTP Muxing", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H264, - .priv_data_size = 0, - .init = fake_h264_init, - .encode2 = fake_h264_frame, - .close = fake_h264_close, - .pix_fmts = (const enum AVPixelFormat[]) { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUVJ420P, - AV_PIX_FMT_NONE - }, -}; - /* Warning: Must be reentrant; this may be called from many device threads at * once */ @@ -92,49 +50,15 @@ static void av_log_cb(void *avcl, int level, const char *fmt, va_list ap) bc_vlog(bc_level, msg, ap); } -static int bc_av_lockmgr(void **mutex_p, enum AVLockOp op) -{ - pthread_mutex_t **mutex = (pthread_mutex_t**)mutex_p; - switch (op) { - case AV_LOCK_CREATE: - *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); - if (!*mutex) - return 1; - return !!pthread_mutex_init(*mutex, NULL); - - case AV_LOCK_OBTAIN: - return !!pthread_mutex_lock(*mutex); - - case AV_LOCK_RELEASE: - return !!pthread_mutex_unlock(*mutex); - - case AV_LOCK_DESTROY: - pthread_mutex_destroy(*mutex); - free(*mutex); - return 0; - } - - return 1; -} - void bc_ffmpeg_init() { - if (av_lockmgr_register(bc_av_lockmgr)) { - bc_log(Fatal, "libav lock registration failed"); - exit(1); - } - - avcodec_register(&fake_h264_encoder); // deprecated - av_register_all(); // deprecated - avfilter_register_all(); // deprecated avformat_network_init(); avdevice_register_all(); - avcodec_register_all(); // deprecated av_log_set_callback(av_log_cb); } void bc_ffmpeg_teardown() { - av_lockmgr_register(NULL); // deprecated + ; } diff --git a/server/media_writer.cpp b/server/media_writer.cpp index da52c946..b88d6a6b 100644 --- a/server/media_writer.cpp +++ b/server/media_writer.cpp @@ -278,7 +278,7 @@ int media_writer::open(const std::string &path, const stream_properties &propert AVCodec *codec; /* Get the output format */ - AVOutputFormat *fmt_out = av_guess_format("mp4", NULL, "video/mp4"); + const AVOutputFormat *fmt_out = av_guess_format("mp4", NULL, "video/mp4"); if (fmt_out == NULL) { bc_log(Error, "media_writer: MP4 output format is not found!"); @@ -707,4 +707,4 @@ int snapshot_writer::write_frame(AVFrame *rawFrame) /////////////////////////////////////////////////////////////// // S.K. >> END-OF: Implementation of separated snapshot writer -/////////////////////////////////////////////////////////////// \ No newline at end of file +/////////////////////////////////////////////////////////////// diff --git a/utils/BCMK b/utils/BCMK index 915f7580..c762ea9d 100644 --- a/utils/BCMK +++ b/utils/BCMK @@ -28,4 +28,4 @@ clean: install: licensecmd ptzcmd $(INSTALL_PROG) -D licensecmd $(DESTDIR)$(libexec_dir)/licensecmd $(INSTALL_PROG) -D ptzcmd $(DESTDIR)$(libexec_dir)/ptzcmd - $(INSTALL_PROG) -D onvif_tool $(DESTDIR)$(libexec_dir)/onvif_tool + $(INSTALL_PROG) -D onvif_tool $(DESTDIR)$(libexec_dir)/onvif_tool || true diff --git a/utils/rtsp-record.c b/utils/rtsp-record.c deleted file mode 100644 index 53717a46..00000000 --- a/utils/rtsp-record.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2010-2019 Bluecherry, LLC - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static void usage(void) -{ - fprintf(stderr, "Usage: rtsp-record rtsp://[USERINFO@]" - "SERVER[:PORT]/ output_file.mkv\n\n"); - exit(EXIT_FAILURE); -} - -/* Fake H.264 encoder for libavcodec. We're only muxing video, never reencoding, - * so a real encoder isn't neeeded, but one must be present for the process to - * succeed. ffmpeg does not support h264 encoding without libx264, which is GPL. - */ - -static int fake_h264_init(AVCodecContext *ctx) -{ - return 0; -} - -static int fake_h264_close(AVCodecContext *ctx) -{ - return 0; -} - -static int fake_h264_frame(AVCodecContext *ctx, uint8_t *buf, int bufsize, void *data) -{ - return -1; -} - -AVCodec fake_h264_encoder = { - .name = "fakeh264", - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H264, - .priv_data_size = 0, - .init = fake_h264_init, - .encode = fake_h264_frame, - .close = fake_h264_close, - .capabilities = CODEC_CAP_DELAY, - .pix_fmts = (const enum PixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_NONE }, - .long_name = "Fake H.264 Encoder for RTP Muxing", -}; - -AVFormatContext *in_ctx; -AVFormatContext *out_ctx; -AVOutputFormat *fmt_out; -AVStream *vst; -int video_stream_index = -1; - -void setup_output(const char *file); - -int main(int argc, char* argv[]) -{ - int opt; - char *url; - - while ((opt = getopt(argc, argv, "h")) != -1) { - switch (opt) { - case 'h': - default: - usage(); - } - } - - if (argc <= (optind+1)) - usage(); - - url = argv[optind++]; - - avcodec_register(&fake_h264_encoder); - av_register_all(); - av_log_set_level(AV_LOG_DEBUG); - - if (avformat_open_input(&in_ctx, url, NULL, NULL) != 0) { - fprintf(stderr, "Could not open URI\n"); - exit(1); - } - - if (avformat_find_stream_info(in_ctx, NULL) < 0) { - fprintf(stderr, "Could not find stream info\n"); - exit(1); - } - - av_dump_format(in_ctx, 0, url, 0); - - setup_output(argv[optind]); - - AVPacket packet, opacket; - int cnt = 0, re; - while ((re = av_read_frame(in_ctx, &packet)) >= 0) { - if (packet.stream_index != video_stream_index) - continue; - av_init_packet(&opacket); - opacket.data = packet.data; - opacket.size = packet.size; - /* For all output framerate issues, look here. */ - opacket.pts = av_rescale_q(packet.pts, (AVRational){1, 90000}, vst->time_base); - opacket.flags = packet.flags; - opacket.stream_index = vst->index; - if (av_write_frame(out_ctx, &opacket)) { - fprintf(stderr, "Error writing video frame\n"); - } - - if (++cnt == 500) - break; - } - - printf("End; last return value %d\n", re); - av_write_trailer(out_ctx); - - exit(0); -} - -void setup_output(const char *file) -{ - AVCodec *codec = 0; - - fmt_out = av_guess_format(NULL, file, NULL); - if (!fmt_out) { - fprintf(stderr, "Could not guess output format\n"); - exit(1); - } - - out_ctx = avformat_alloc_context(); - if (!out_ctx) { - fprintf(stderr, "Could not alloc context\n"); - exit(1); - } - - out_ctx->oformat = fmt_out; - snprintf(out_ctx->filename, sizeof(out_ctx->filename), "%s", file); - - vst = avformat_new_stream(out_ctx, 0); - if (!vst) { - fprintf(stderr, "Could not add video stream\n"); - exit(1); - } - - int i; - for (i = 0; i < in_ctx->nb_streams; ++i) { - if (in_ctx->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) - continue; - - printf("Found video codec!\n"); - video_stream_index = i; - - AVCodecContext *ic = in_ctx->streams[i]->codec; - codec = avcodec_find_encoder(in_ctx->streams[i]->codecpar->codec_id); - vst->codec->codec_id = ic->codec_id; - vst->codec->codec_type = ic->codec_type; - vst->codec->pix_fmt = ic->pix_fmt; - vst->codec->width = ic->width; - vst->codec->height = ic->height; - vst->codec->time_base = ic->time_base; - - break; - } - - if (out_ctx->oformat->flags & AVFMT_GLOBALHEADER) - vst->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; - -#if 0 - if (rs->tid_a >= 0 || rs->aud_port >= 0) { - ast = avformat_new_stream(out_ctx, 1); - if (!ast) { - fprintf(stderr, "Could not add audio stream\n"); - exit(1); - } - - ast->codec->codec_id = rs->aud_codec; - ast->codec->codec_type = CODEC_TYPE_AUDIO; - ast->codec->bit_rate = rs->bitrate; - ast->codec->sample_rate = rs->samplerate; - ast->codec->channels = rs->channels; - ast->codec->time_base = (AVRational){1, rs->samplerate}; - - if (out_ctx->oformat->flags & AVFMT_GLOBALHEADER) - ast->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; - } -#endif - - if (av_set_parameters(out_ctx, NULL) < 0) { - fprintf(stderr, "Could not set params\n"); - exit(1); - } - - if (codec == NULL || avcodec_open(vst->codec, codec) < 0) { - fprintf(stderr, "Could not open video encoder\n"); - exit(1); - } - - if (avio_open(&out_ctx->pb, file, AVIO_FLAG_WRITE) < 0) { - fprintf(stderr, "Could not open outfile\n"); - exit(1); - } - - av_write_header(out_ctx); -} diff --git a/www/lib/lib.php b/www/lib/lib.php index ad3e2e84..9289e891 100644 --- a/www/lib/lib.php +++ b/www/lib/lib.php @@ -933,7 +933,7 @@ public function changeState(){ if (!$this->info['disabled']) { self::autoConfigure($this->info['driver'], $this->info); } return array(data::query("UPDATE Devices SET disabled=".(($this->info['disabled']) ? 0 : 1)." WHERE id={$this->info['id']}", true)); } - private function checkLimitDevices(){ + private static function checkLimitDevices(){ $info = data::query("SELECT COUNT(*) as n FROM Devices WHERE protocol in ('IP-RTSP', 'IP-MJPEG', 'IP')"); $total_devices = $info[0]['n'];