commit
1bc53827d8
@ -6,12 +6,10 @@ This web GUI is for managing [ffplayout-engine](https://github.com/ffplayout/ffp
|
|||||||
For a better understanding about the functionality, take a look to the screenshots below.
|
For a better understanding about the functionality, take a look to the screenshots below.
|
||||||
The Interface is mostly made for 24/7 streaming. Other scenarios like streaming in folder mode or playlists with no starting time will work, but is not shown correctly.
|
The Interface is mostly made for 24/7 streaming. Other scenarios like streaming in folder mode or playlists with no starting time will work, but is not shown correctly.
|
||||||
|
|
||||||
You can install it on a fresh Debian/CentOS minimal like system with running `./install.sh` as root.
|
You can install it on a fresh Debian like system with the [standalone installer](https://github.com/ffplayout/ffplayout-installer).
|
||||||
|
|
||||||
**Recommend system is a current Debian version.**
|
**Recommend system is a current Debian version.**
|
||||||
|
|
||||||
Updating is also possible with: `./install.sh update`
|
|
||||||
|
|
||||||
Or read the instruction [install.md](docs/install.md) for manual installation.
|
Or read the instruction [install.md](docs/install.md) for manual installation.
|
||||||
|
|
||||||
After installations you have to setup ssl for your **https** connections.
|
After installations you have to setup ssl for your **https** connections.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#__nuxt, #__layout, #__layout > div, #__layout > div > div {
|
#__nuxt, #__layout, #__layout > div, #__layout > div > div {
|
||||||
height: 100%
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face{
|
@font-face{
|
||||||
|
687
install.sh
687
install.sh
@ -1,687 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
if [[ $(whoami) != 'root' ]]; then
|
|
||||||
echo "This script must run under root!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$(grep -Ei 'centos|fedora' /etc/*release)" ]]; then
|
|
||||||
serviceUser="nginx"
|
|
||||||
else
|
|
||||||
serviceUser="www-data"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# get sure that we have our correct PATH
|
|
||||||
export PATH=$PATH:/usr/local/bin
|
|
||||||
export NUXT_TELEMETRY_DISABLED=1
|
|
||||||
|
|
||||||
runInstall() {
|
|
||||||
if [[ ! -f "/etc/ffplayout/ffplayout.yml" ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "path to media storage, default: /opt/ffplayout/media"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
read -p "media path :$ " mediaPath
|
|
||||||
|
|
||||||
if [[ -z "$mediaPath" ]]; then
|
|
||||||
mediaPath="/opt/ffplayout/media"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "playlist path, default: /opt/ffplayout/playlists"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
read -p "playlist path :$ " playlistPath
|
|
||||||
|
|
||||||
if [[ -z "$playlistPath" ]]; then
|
|
||||||
playlistPath="/opt/ffplayout/playlists"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! ffmpeg -version &> /dev/null; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "compile and install (nonfree) ffmpeg:"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo ""
|
|
||||||
while true; do
|
|
||||||
read -p "Do you wish to compile ffmpeg? (Y/n) :$ " yn
|
|
||||||
case $yn in
|
|
||||||
[Yy]* ) compileFFmpeg="y"; break;;
|
|
||||||
[Nn]* ) compileFFmpeg="n"; break;;
|
|
||||||
* ) (
|
|
||||||
echo "------------------------------------"
|
|
||||||
echo "Please answer yes or no!"
|
|
||||||
echo ""
|
|
||||||
);;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! nginx -t &> /dev/null; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "install and setup nginx:"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo ""
|
|
||||||
while true; do
|
|
||||||
read -p "Do you wish to install nginx? (Y/n) :$ " yn
|
|
||||||
case $yn in
|
|
||||||
[Yy]* ) installNginx="y"; break;;
|
|
||||||
[Nn]* ) installNginx="n"; break;;
|
|
||||||
* ) (
|
|
||||||
echo "------------------------------------"
|
|
||||||
echo "Please answer yes or no!"
|
|
||||||
echo ""
|
|
||||||
);;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "ffplayout domain name (like: example.org)"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
read -p "domain name :$ " domainFrontend
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -d /usr/local/srs ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "install and srs rtmp/hls server:"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo ""
|
|
||||||
while true; do
|
|
||||||
read -p "Do you wish to install srs? (Y/n) :$ " yn
|
|
||||||
case $yn in
|
|
||||||
[Yy]* ) installSRS="y"; break;;
|
|
||||||
[Nn]* ) installSRS="n"; break;;
|
|
||||||
* ) (
|
|
||||||
echo "------------------------------------"
|
|
||||||
echo "Please answer yes or no!"
|
|
||||||
echo ""
|
|
||||||
);;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -d "/opt/ffplayout-engine" ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "install ffplayout-engine:"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo ""
|
|
||||||
while true; do
|
|
||||||
read -p "Do you wish to install ffplayout-engine? (Y/n) :$ " yn
|
|
||||||
case $yn in
|
|
||||||
[Yy]* ) installEngine="y"; break;;
|
|
||||||
[Nn]* ) installEngine="n"; break;;
|
|
||||||
* ) (
|
|
||||||
echo "------------------------------------"
|
|
||||||
echo "Please answer yes or no!"
|
|
||||||
echo ""
|
|
||||||
);;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "install main packages"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
if [[ "$(grep -Ei 'debian|buntu|mint' /etc/*release)" ]]; then
|
|
||||||
packages=(sudo curl wget net-tools git python3-dev build-essential virtualenv
|
|
||||||
python3-virtualenv mediainfo autoconf automake libtool pkg-config
|
|
||||||
yasm cmake mercurial gperf)
|
|
||||||
installedPackages=$(dpkg --get-selections | awk '{print $1}' | tr '\n' ' ')
|
|
||||||
apt update
|
|
||||||
|
|
||||||
if [[ "$installedPackages" != *"curl"* ]]; then
|
|
||||||
apt install -y curl
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$installedPackages" != *"nodejs"* ]]; then
|
|
||||||
curl -sL https://deb.nodesource.com/setup_12.x | bash -
|
|
||||||
apt install -y nodejs
|
|
||||||
fi
|
|
||||||
|
|
||||||
for pkg in ${packages[@]}; do
|
|
||||||
if [[ "$installedPackages" != *"$pkg"* ]]; then
|
|
||||||
apt install -y $pkg
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ $installNginx == 'y' ]] && [[ "$installedPackages" != *"nginx"* ]]; then
|
|
||||||
apt install -y nginx
|
|
||||||
rm /etc/nginx/sites-enabled/default
|
|
||||||
fi
|
|
||||||
|
|
||||||
nginxConfig="/etc/nginx/sites-available"
|
|
||||||
|
|
||||||
elif [[ "$(grep -Ei 'centos|fedora' /etc/*release)" ]]; then
|
|
||||||
packages=(libstdc++-static yasm mercurial libtool libmediainfo mediainfo
|
|
||||||
cmake net-tools git python3 python36-devel wget python3-virtualenv
|
|
||||||
gperf nano nodejs python3-policycoreutils policycoreutils-devel)
|
|
||||||
installedPackages=$(dnf list --installed | awk '{print $1}' | tr '\n' ' ')
|
|
||||||
activeRepos=$(dnf repolist enabled | awk '{print $1}' | tr '\n' ' ')
|
|
||||||
|
|
||||||
if [[ "$activeRepos" != *"epel"* ]]; then
|
|
||||||
dnf -y install epel-release
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$activeRepos" != *"PowerTools"* ]]; then
|
|
||||||
dnf -y config-manager --enable PowerTools
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$activeRepos" != *"nodesource"* ]]; then
|
|
||||||
curl -sL https://rpm.nodesource.com/setup_12.x | sudo -E bash -
|
|
||||||
fi
|
|
||||||
|
|
||||||
for pkg in ${packages[@]}; do
|
|
||||||
if [[ "$installedPackages" != *"$pkg"* ]]; then
|
|
||||||
dnf -y install $pkg
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ ! $(dnf group list "Development Tools" | grep -i "install") ]]; then
|
|
||||||
dnf -y group install "Development Tools"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $installNginx == 'y' ]] && [[ "$installedPackages" != *"nginx"* ]]; then
|
|
||||||
dnf -y install nginx
|
|
||||||
systemctl enable nginx
|
|
||||||
systemctl start nginx
|
|
||||||
firewall-cmd --permanent --add-service=http
|
|
||||||
firewall-cmd --permanent --zone=public --add-service=https
|
|
||||||
firewall-cmd --reload
|
|
||||||
mkdir /var/www
|
|
||||||
chcon -vR system_u:object_r:httpd_sys_content_t:s0 /var/www
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $(alternatives --list | grep "no-python") ]]; then
|
|
||||||
alternatives --set python /usr/bin/python3
|
|
||||||
fi
|
|
||||||
|
|
||||||
nginxConfig="/etc/nginx/conf.d"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $compileFFmpeg == 'y' ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "compile and install ffmpeg"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
cd /opt/
|
|
||||||
|
|
||||||
if [[ ! -d "ffmpeg-build" ]]; then
|
|
||||||
git clone https://github.com/jb-alvarado/compile-ffmpeg-osx-linux.git ffmpeg-build
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ffmpeg-build
|
|
||||||
|
|
||||||
if [[ ! -f "build_config.txt" ]]; then
|
|
||||||
cat <<EOF > "build_config.txt"
|
|
||||||
#--enable-decklink
|
|
||||||
--disable-ffplay
|
|
||||||
--disable-sdl2
|
|
||||||
--enable-fontconfig
|
|
||||||
#--enable-libaom
|
|
||||||
#--enable-libass
|
|
||||||
#--enable-libbluray
|
|
||||||
--enable-libfdk-aac
|
|
||||||
--enable-libfribidi
|
|
||||||
--enable-libfreetype
|
|
||||||
--enable-libmp3lame
|
|
||||||
--enable-libopus
|
|
||||||
--enable-libsoxr
|
|
||||||
#--enable-libsrt
|
|
||||||
--enable-libtwolame
|
|
||||||
--enable-libvpx
|
|
||||||
--enable-libx264
|
|
||||||
--enable-libx265
|
|
||||||
--enable-libzimg
|
|
||||||
--enable-libzmq
|
|
||||||
--enable-nonfree
|
|
||||||
#--enable-opencl
|
|
||||||
#--enable-opengl
|
|
||||||
#--enable-openssl
|
|
||||||
#--enable-libsvtav1
|
|
||||||
EOF
|
|
||||||
sed -i 's/mediainfo="yes"/mediainfo="no"/g' ./compile-ffmpeg.sh
|
|
||||||
sed -i 's/mp4box="yes"/mp4box="no"/g' ./compile-ffmpeg.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
./compile-ffmpeg.sh
|
|
||||||
|
|
||||||
\cp local/bin/ff* /usr/local/bin/
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $installSRS == 'y' ]] && [[ ! -d "/usr/local/srs" ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "compile and install srs"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
cd /opt/
|
|
||||||
git clone https://github.com/ossrs/srs.git
|
|
||||||
cd srs/trunk/
|
|
||||||
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
|
|
||||||
mkdir -p "/var/www/srs/live"
|
|
||||||
mkdir "/etc/srs"
|
|
||||||
|
|
||||||
cat <<EOF > "/etc/srs/srs.conf"
|
|
||||||
listen 1935;
|
|
||||||
max_connections 20;
|
|
||||||
daemon on;
|
|
||||||
pid /usr/local/srs/objs/srs.pid;
|
|
||||||
srs_log_tank console; # file;
|
|
||||||
srs_log_file /var/log/srs.log;
|
|
||||||
ff_log_dir /tmp;
|
|
||||||
|
|
||||||
# can be: verbose, info, trace, warn, error
|
|
||||||
srs_log_level error;
|
|
||||||
|
|
||||||
http_api {
|
|
||||||
enabled on;
|
|
||||||
listen 1985;
|
|
||||||
}
|
|
||||||
|
|
||||||
stats {
|
|
||||||
network 0;
|
|
||||||
disk sda vda xvda xvdb;
|
|
||||||
}
|
|
||||||
|
|
||||||
vhost __defaultVhost__ {
|
|
||||||
# timestamp correction
|
|
||||||
mix_correct on;
|
|
||||||
|
|
||||||
http_hooks {
|
|
||||||
enabled off;
|
|
||||||
on_publish http://127.0.0.1:8085/api/v1/streams;
|
|
||||||
on_unpublish http://127.0.0.1:8085/api/v1/streams;
|
|
||||||
}
|
|
||||||
|
|
||||||
hls {
|
|
||||||
enabled on;
|
|
||||||
hls_path /var/www/srs;
|
|
||||||
hls_fragment 6;
|
|
||||||
hls_window 3600;
|
|
||||||
hls_cleanup on;
|
|
||||||
hls_dispose 0;
|
|
||||||
hls_m3u8_file live/stream.m3u8;
|
|
||||||
hls_ts_file live/stream-[seq].ts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<EOF > "/etc/systemd/system/srs.service"
|
|
||||||
[Unit]
|
|
||||||
Description=SRS
|
|
||||||
Documentation=https://github.com/ossrs/srs/wiki
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=forking
|
|
||||||
ExecStartPre=/usr/local/srs/objs/srs -t -c /etc/srs/srs.conf
|
|
||||||
ExecStart=/usr/local/srs/objs/srs -c /etc/srs/srs.conf
|
|
||||||
ExecStop=/bin/kill -TERM \$MAINPID
|
|
||||||
ExecReload=/bin/kill -1 \$MAINPID
|
|
||||||
Restart=always
|
|
||||||
RestartSec=3
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF
|
|
||||||
|
|
||||||
systemctl enable srs.service
|
|
||||||
systemctl start srs.service
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$(grep -Ei 'centos|fedora' /etc/*release)" ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "creating selinux rules"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
if [[ $(getsebool httpd_can_network_connect | awk '{print $NF}') == "off" ]]; then
|
|
||||||
setsebool httpd_can_network_connect on -P
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $(semanage port -l | grep http_port_t | grep "8001") ]]; then
|
|
||||||
semanage port -a -t http_port_t -p tcp 8001
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $(semodule -l | grep gunicorn) ]]; then
|
|
||||||
cat <<EOF > gunicorn.te
|
|
||||||
module gunicorn 1.0;
|
|
||||||
|
|
||||||
require {
|
|
||||||
type init_t;
|
|
||||||
type httpd_sys_content_t;
|
|
||||||
type unreserved_port_t;
|
|
||||||
class tcp_socket name_connect;
|
|
||||||
type etc_t;
|
|
||||||
type sudo_exec_t;
|
|
||||||
class file { create execute execute_no_trans getattr ioctl lock map open read unlink write };
|
|
||||||
class lnk_file { getattr read };
|
|
||||||
}
|
|
||||||
|
|
||||||
#============= init_t ==============
|
|
||||||
|
|
||||||
#!!!! This avc is allowed in the current policy
|
|
||||||
allow init_t etc_t:file write;
|
|
||||||
|
|
||||||
#!!!! This avc is allowed in the current policy
|
|
||||||
#!!!! This av rule may have been overridden by an extended permission av rule
|
|
||||||
allow init_t httpd_sys_content_t:file { create execute execute_no_trans getattr ioctl lock map open read unlink write };
|
|
||||||
|
|
||||||
#!!!! This avc is allowed in the current policy
|
|
||||||
allow init_t httpd_sys_content_t:lnk_file { getattr read };
|
|
||||||
|
|
||||||
#!!!! This avc can be allowed using the boolean 'nis_enabled'
|
|
||||||
allow init_t unreserved_port_t:tcp_socket name_connect;
|
|
||||||
|
|
||||||
#!!!! This avc is allowed in the current policy
|
|
||||||
allow init_t sudo_exec_t:file { execute execute_no_trans map open read };
|
|
||||||
EOF
|
|
||||||
|
|
||||||
checkmodule -M -m -o gunicorn.mod gunicorn.te
|
|
||||||
semodule_package -o gunicorn.pp -m gunicorn.mod
|
|
||||||
semodule -i gunicorn.pp
|
|
||||||
|
|
||||||
rm -f gunicorn.*
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $(semodule -l | grep "custom-http") ]]; then
|
|
||||||
cat <<EOF > custom-http.te
|
|
||||||
module custom-http 1.0;
|
|
||||||
|
|
||||||
require {
|
|
||||||
type init_t;
|
|
||||||
type httpd_sys_content_t;
|
|
||||||
class file { create lock unlink write };
|
|
||||||
}
|
|
||||||
|
|
||||||
#============= init_t ==============
|
|
||||||
allow init_t httpd_sys_content_t:file unlink;
|
|
||||||
|
|
||||||
#!!!! This avc is allowed in the current policy
|
|
||||||
allow init_t httpd_sys_content_t:file { create lock write };
|
|
||||||
EOF
|
|
||||||
|
|
||||||
checkmodule -M -m -o custom-http.mod custom-http.te
|
|
||||||
semodule_package -o custom-http.pp -m custom-http.mod
|
|
||||||
semodule -i custom-http.pp
|
|
||||||
|
|
||||||
rm -f custom-http.*
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! $(semodule -l | grep "custom-fileop") ]]; then
|
|
||||||
cat <<EOF > custom-fileop.te
|
|
||||||
module custom-fileop 1.0;
|
|
||||||
|
|
||||||
require {
|
|
||||||
type init_t;
|
|
||||||
type httpd_sys_content_t;
|
|
||||||
type usr_t;
|
|
||||||
class file { create rename unlink write };
|
|
||||||
class dir { create rmdir };
|
|
||||||
}
|
|
||||||
|
|
||||||
#============= init_t ==============
|
|
||||||
allow init_t httpd_sys_content_t:file rename;
|
|
||||||
|
|
||||||
#!!!! This avc is allowed in the current policy
|
|
||||||
allow init_t usr_t:dir create;
|
|
||||||
allow init_t usr_t:dir rmdir;
|
|
||||||
|
|
||||||
#!!!! This avc is allowed in the current policy
|
|
||||||
allow init_t usr_t:file create;
|
|
||||||
allow init_t usr_t:file { rename unlink write };
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
checkmodule -M -m -o custom-fileop.mod custom-fileop.te
|
|
||||||
semodule_package -o custom-fileop.pp -m custom-fileop.mod
|
|
||||||
semodule -i custom-fileop.pp
|
|
||||||
|
|
||||||
rm -f custom-fileop.*
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! grep -q "ffplayout-engine.service" "/etc/sudoers"; then
|
|
||||||
echo "$serviceUser ALL = NOPASSWD: /bin/systemctl start ffplayout-engine.service, /bin/systemctl stop ffplayout-engine.service, /bin/systemctl reload ffplayout-engine.service, /bin/systemctl restart ffplayout-engine.service, /bin/systemctl status ffplayout-engine.service, /bin/systemctl is-active ffplayout-engine.service, /bin/journalctl -n 1000 -u ffplayout-engine.service" >> /etc/sudoers
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$installEngine" == "y" ]] && [[ ! -d "/opt/ffplayout-engine" ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "install ffplayout engine"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
cd /opt
|
|
||||||
git clone https://github.com/ffplayout/ffplayout-engine.git
|
|
||||||
cd ffplayout-engine
|
|
||||||
|
|
||||||
virtualenv -p python3 venv
|
|
||||||
source ./venv/bin/activate
|
|
||||||
|
|
||||||
pip install -r requirements-base.txt
|
|
||||||
|
|
||||||
mkdir /etc/ffplayout
|
|
||||||
mkdir /var/log/ffplayout
|
|
||||||
mkdir -p $mediaPath
|
|
||||||
mkdir -p $playlistPath
|
|
||||||
|
|
||||||
cp ffplayout.yml /etc/ffplayout/
|
|
||||||
chown -R $serviceUser. /etc/ffplayout
|
|
||||||
chown $serviceUser. /var/log/ffplayout
|
|
||||||
chown $serviceUser. $mediaPath
|
|
||||||
chown $serviceUser. $playlistPath
|
|
||||||
|
|
||||||
cp docs/ffplayout-engine.service /etc/systemd/system/
|
|
||||||
sed -i "s/User=root/User=$serviceUser/g" /etc/systemd/system/ffplayout-engine.service
|
|
||||||
sed -i "s/Group=root/Group=$serviceUser/g" /etc/systemd/system/ffplayout-engine.service
|
|
||||||
|
|
||||||
sed -i "s|\"\/playlists\"|\"$playlistPath\"|g" /etc/ffplayout/ffplayout.yml
|
|
||||||
sed -i "s|\"\/mediaStorage|\"$mediaPath|g" /etc/ffplayout/ffplayout.yml
|
|
||||||
|
|
||||||
systemctl enable ffplayout-engine.service
|
|
||||||
|
|
||||||
deactivate
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -d "/var/www/ffplayout-api" ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "install ffplayout-api"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
cd /var/www
|
|
||||||
git clone https://github.com/ffplayout/ffplayout-api.git
|
|
||||||
cd ffplayout-api
|
|
||||||
|
|
||||||
virtualenv -p python3 venv
|
|
||||||
source ./venv/bin/activate
|
|
||||||
|
|
||||||
pip install -r requirements-base.txt
|
|
||||||
|
|
||||||
cd ffplayout
|
|
||||||
|
|
||||||
secret=$(python manage.py shell -c 'from django.core.management import utils; print(utils.get_random_secret_key())')
|
|
||||||
|
|
||||||
sed -i "s/---a-very-important-secret-key\:-generate-it-new---/$secret/g" ffplayout/settings/production.py
|
|
||||||
sed -i "s/localhost/$domainFrontend/g" ../docs/db_data.json
|
|
||||||
|
|
||||||
python manage.py makemigrations && python manage.py migrate
|
|
||||||
python manage.py collectstatic
|
|
||||||
python manage.py loaddata ../docs/db_data.json
|
|
||||||
python manage.py createsuperuser
|
|
||||||
|
|
||||||
deactivate
|
|
||||||
|
|
||||||
chown $serviceUser. -R /var/www
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
cp docs/ffplayout-api.service /etc/systemd/system/
|
|
||||||
|
|
||||||
sed -i "s/User=root/User=$serviceUser/g" /etc/systemd/system/ffplayout-api.service
|
|
||||||
sed -i "s/Group=root/Group=$serviceUser/g" /etc/systemd/system/ffplayout-api.service
|
|
||||||
|
|
||||||
sed -i "s/'localhost'/'localhost', \'$domainFrontend\'/g" /var/www/ffplayout-api/ffplayout/ffplayout/settings/production.py
|
|
||||||
sed -i "s/ffplayout\\.local/$domainFrontend\'\n \'https\\:\/\/$domainFrontend/g" /var/www/ffplayout-api/ffplayout/ffplayout/settings/production.py
|
|
||||||
|
|
||||||
systemctl enable ffplayout-api.service
|
|
||||||
systemctl start ffplayout-api.service
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -d "/var/www/ffplayout-frontend" ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "install ffplayout-frontend"
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
cd /var/www
|
|
||||||
git clone https://github.com/ffplayout/ffplayout-frontend.git
|
|
||||||
cd ffplayout-frontend
|
|
||||||
|
|
||||||
ln -s "$mediaPath" /var/www/ffplayout-frontend/static/
|
|
||||||
|
|
||||||
npm install
|
|
||||||
|
|
||||||
cat <<EOF > ".env"
|
|
||||||
BASE_URL='http://$domainFrontend'
|
|
||||||
API_URL='/'
|
|
||||||
EOF
|
|
||||||
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
chown $serviceUser. -R /var/www
|
|
||||||
|
|
||||||
if [[ $installNginx == 'y' ]]; then
|
|
||||||
cp docs/ffplayout.conf "$nginxConfig/"
|
|
||||||
|
|
||||||
origin=$(echo "$domainFrontend" | sed 's/\./\\\\./g')
|
|
||||||
|
|
||||||
sed -i "s/ffplayout.local/$domainFrontend/g" $nginxConfig/ffplayout.conf
|
|
||||||
sed -i "s/ffplayout\\\.local/$origin/g" $nginxConfig/ffplayout.conf
|
|
||||||
|
|
||||||
if [[ "$(grep -Ei 'debian|buntu|mint' /etc/*release)" ]]; then
|
|
||||||
ln -s $nginxConfig/ffplayout.conf /etc/nginx/sites-enabled/
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $installNginx == 'y' ]]; then
|
|
||||||
systemctl restart nginx
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "installation done..."
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "add your ssl config to $nginxConfig/ffplayout.conf"
|
|
||||||
echo ""
|
|
||||||
}
|
|
||||||
|
|
||||||
runUpdate() {
|
|
||||||
if [[ -d "/opt/ffmpeg-build" ]]; then
|
|
||||||
cd "/opt/ffmpeg-build"
|
|
||||||
|
|
||||||
git pull
|
|
||||||
|
|
||||||
./compile-ffmpeg.sh
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "updating ffmpeg-build done..."
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -d "/opt/ffplayout-engine" ]]; then
|
|
||||||
cd "/opt/ffplayout-engine"
|
|
||||||
git pull
|
|
||||||
|
|
||||||
source ./venv/bin/activate
|
|
||||||
pip install --upgrade -r requirements-base.txt
|
|
||||||
deactivate
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "updating ffplayout-engine done..."
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "WARNING: no ffplayout-engine found..."
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -d "/var/www/ffplayout-api" ]]; then
|
|
||||||
cd "/var/www/ffplayout-api"
|
|
||||||
git pull
|
|
||||||
|
|
||||||
source ./venv/bin/activate
|
|
||||||
pip install --upgrade -r requirements-base.txt
|
|
||||||
deactivate
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "updating ffplayout-api done..."
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "WARNING: no ffplayout-api found..."
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -d "/var/www/ffplayout-frontend" ]]; then
|
|
||||||
cd "/var/www/ffplayout-frontend"
|
|
||||||
git pull
|
|
||||||
|
|
||||||
rm -rf node_modules
|
|
||||||
sudo -H -u $serviceUser bash -c 'npm install'
|
|
||||||
sudo -H -u $serviceUser bash -c 'npm run build'
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "updating ffplayout-frontend done..."
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "WARNING: no ffplayout-frontend found..."
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "------------------------------------------------------------------------------"
|
|
||||||
echo "updating done..."
|
|
||||||
echo "if there is a new ffmpeg version, run:"
|
|
||||||
echo " systemctl stop ffplayout-engine"
|
|
||||||
echo " cp /opt/ffmpeg-build/local/bin/ff* /usrlocal/bin"
|
|
||||||
echo " systemctl start ffplayout-engine"
|
|
||||||
echo ""
|
|
||||||
echo "to apply update restart services:"
|
|
||||||
echo " systemctl restart ffplayout-engine"
|
|
||||||
echo " systemctl restart ffplayout-api"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [[ "$1" == "update" ]]; then
|
|
||||||
runUpdate
|
|
||||||
else
|
|
||||||
runInstall
|
|
||||||
fi
|
|
@ -44,6 +44,7 @@ html, body {
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -44,12 +44,12 @@ export default {
|
|||||||
plugins: [
|
plugins: [
|
||||||
{ src: '~/plugins/axios' },
|
{ src: '~/plugins/axios' },
|
||||||
{ src: '~/plugins/filters' },
|
{ src: '~/plugins/filters' },
|
||||||
|
{ src: '~/plugins/helpers.js' },
|
||||||
{ src: '~/plugins/nuxt-client-init.js', ssr: false },
|
{ src: '~/plugins/nuxt-client-init.js', ssr: false },
|
||||||
{ src: '~plugins/video.js', ssr: false },
|
{ src: '~plugins/video.js', ssr: false },
|
||||||
{ src: '~plugins/scrollbar.js', ssr: false },
|
{ src: '~plugins/scrollbar.js', ssr: false },
|
||||||
{ src: '~plugins/splitpanes.js', ssr: false },
|
{ src: '~plugins/splitpanes.js', ssr: false },
|
||||||
{ src: '~plugins/loading.js', ssr: false },
|
{ src: '~plugins/loading.js', ssr: false },
|
||||||
{ src: '~/plugins/helpers.js' },
|
|
||||||
{ src: '~plugins/draggable.js', ssr: false }
|
{ src: '~plugins/draggable.js', ssr: false }
|
||||||
],
|
],
|
||||||
/*
|
/*
|
||||||
|
@ -6,12 +6,12 @@
|
|||||||
<b-datepicker v-model="listDate" size="sm" class="date-div" offset="-35px" />
|
<b-datepicker v-model="listDate" size="sm" class="date-div" offset="-35px" />
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<b-card no-body>
|
<b-card no-body class="card-container">
|
||||||
<b-tabs pills card vertical>
|
<b-tabs pills card vertical>
|
||||||
<b-tab title="Playout" active @click="getLog('ffplayout')">
|
<b-tab title="Playout" active @click="getLog('ffplayout')">
|
||||||
<b-container class="log-container">
|
<b-container class="log-container">
|
||||||
<!-- eslint-disable-next-line -->
|
<!-- eslint-disable-next-line -->
|
||||||
<pre v-if="currentLog" :inner-html.prop="currentLog | formatStr" class="log-content" />
|
<perfect-scrollbar :options="scrollOP" class="scroll-container log-content" v-if="currentLog" :inner-html.prop="currentLog | formatStr" />
|
||||||
</b-container>
|
</b-container>
|
||||||
</b-tab>
|
</b-tab>
|
||||||
<b-tab title="Decoder" @click="getLog('decoder')">
|
<b-tab title="Decoder" @click="getLog('decoder')">
|
||||||
@ -63,7 +63,10 @@ export default {
|
|||||||
return {
|
return {
|
||||||
logName: 'ffplayout',
|
logName: 'ffplayout',
|
||||||
currentLog: null,
|
currentLog: null,
|
||||||
listDate: this.$dayjs().format('YYYY-MM-DD')
|
listDate: this.$dayjs().format('YYYY-MM-DD'),
|
||||||
|
scrollOP: {
|
||||||
|
wheelSpeed: 5
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -97,18 +100,45 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.ps__thumb-x {
|
||||||
|
display: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
.col-auto {
|
.col-auto {
|
||||||
width: 122px;
|
width: 122px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-container {
|
||||||
|
height: calc(100% - 90px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-container > div, .tab-content > .active {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-content {
|
.tab-content {
|
||||||
max-width: calc(100% - 122px);
|
width: calc(100% - 122px);
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-container {
|
.log-container {
|
||||||
background: #1d2024;
|
background: #1d2024;
|
||||||
max-width: 95%;
|
max-width: 100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
|
overflow: hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
white-space: pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-content {
|
.log-content {
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<splitpanes class="browser-row default-theme pane-row">
|
<splitpanes class="browser-row default-theme pane-row">
|
||||||
<pane min-size="20" size="24">
|
<pane min-size="20" size="24">
|
||||||
<div class="browser-div">
|
<div class="browser-div">
|
||||||
<perfect-scrollbar>
|
<perfect-scrollbar :options="scrollOP">
|
||||||
<b-list-group class="folder-list">
|
<b-list-group class="folder-list">
|
||||||
<b-list-group-item
|
<b-list-group-item
|
||||||
v-for="folder in folderTree.tree[1]"
|
v-for="folder in folderTree.tree[1]"
|
||||||
@ -67,7 +67,7 @@
|
|||||||
color="#ff9c36"
|
color="#ff9c36"
|
||||||
/>
|
/>
|
||||||
<div class="browser-div">
|
<div class="browser-div">
|
||||||
<perfect-scrollbar>
|
<perfect-scrollbar :options="scrollOP">
|
||||||
<b-list-group class="files-list">
|
<b-list-group class="files-list">
|
||||||
<b-list-group-item
|
<b-list-group-item
|
||||||
v-for="file in folderTree.tree[2]"
|
v-for="file in folderTree.tree[2]"
|
||||||
@ -289,7 +289,10 @@ export default {
|
|||||||
overallProgress: 0,
|
overallProgress: 0,
|
||||||
currentProgress: 0,
|
currentProgress: 0,
|
||||||
cancelTokenSource: this.$axios.CancelToken.source(),
|
cancelTokenSource: this.$axios.CancelToken.source(),
|
||||||
lastPath: ''
|
lastPath: '',
|
||||||
|
scrollOP: {
|
||||||
|
suppressScrollX: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -220,9 +220,6 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
<b-col class="grabbing">
|
<b-col class="grabbing">
|
||||||
{{ item.source | filename }}
|
{{ item.source | filename }}
|
||||||
<div class="clip-progress">
|
|
||||||
<b-progress v-if="index === currentClipIndex" height="2px" :value="progressValue" />
|
|
||||||
</div>
|
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="1" class="text-center playlist-input">
|
<b-col cols="1" class="text-center playlist-input">
|
||||||
<b-link @click="showModal(item.source)">
|
<b-link @click="showModal(item.source)">
|
||||||
@ -298,6 +295,21 @@
|
|||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import Menu from '@/components/Menu.vue'
|
import Menu from '@/components/Menu.vue'
|
||||||
|
|
||||||
|
function scrollTo (t) {
|
||||||
|
let child
|
||||||
|
if (t.currentClipIndex === null) {
|
||||||
|
child = document.getElementById('clip_0')
|
||||||
|
} else {
|
||||||
|
child = document.getElementById(`clip_${t.currentClipIndex}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child) {
|
||||||
|
const parent = document.getElementById('scroll-container')
|
||||||
|
const topPos = child.offsetTop
|
||||||
|
parent.scrollTop = topPos - 50
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Player',
|
name: 'Player',
|
||||||
|
|
||||||
@ -324,8 +336,7 @@ export default {
|
|||||||
videoOptions: {},
|
videoOptions: {},
|
||||||
previewOptions: {},
|
previewOptions: {},
|
||||||
previewComp: null,
|
previewComp: null,
|
||||||
previewSource: '',
|
previewSource: ''
|
||||||
autoScroll: true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -347,6 +358,7 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
listDate (date) {
|
listDate (date) {
|
||||||
this.getPlaylist()
|
this.getPlaylist()
|
||||||
|
setTimeout(() => { scrollTo(this) }, 5000)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -371,25 +383,26 @@ export default {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const timeInSec = this.$timeToSeconds(this.$dayjs().format('HH:mm:ss'))
|
||||||
|
const listStartSec = this.$timeToSeconds(this.configPlayout.playlist.day_start)
|
||||||
|
|
||||||
|
if (listStartSec > timeInSec) {
|
||||||
|
this.listDate = this.$dayjs(this.listDate).subtract(1, 'day').format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
|
||||||
await this.getPlaylist()
|
await this.getPlaylist()
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted () {
|
mounted () {
|
||||||
if (!process.env.DEV) {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
this.interval = setInterval(() => {
|
this.interval = setInterval(() => {
|
||||||
this.$store.dispatch('playlist/animClock')
|
this.$store.dispatch('playlist/animClock')
|
||||||
const child = document.getElementById(`clip_${this.currentClipIndex}`)
|
|
||||||
|
|
||||||
if (child && this.autoScroll) {
|
|
||||||
const parent = document.getElementById('scroll-container')
|
|
||||||
const topPos = child.offsetTop
|
|
||||||
parent.scrollTop = topPos - 50
|
|
||||||
this.autoScroll = false
|
|
||||||
}
|
|
||||||
}, 5000)
|
}, 5000)
|
||||||
} else {
|
} else {
|
||||||
this.$store.dispatch('playlist/animClock')
|
this.$store.dispatch('playlist/animClock')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTimeout(() => { scrollTo(this) }, 4000)
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
@ -707,7 +720,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.active-playlist-clip {
|
.active-playlist-clip {
|
||||||
background-color: #49515c !important;
|
background-color: #565e6a !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -4,6 +4,8 @@ export const state = () => ({
|
|||||||
configGui: null,
|
configGui: null,
|
||||||
configGuiRaw: null,
|
configGuiRaw: null,
|
||||||
netChoices: [],
|
netChoices: [],
|
||||||
|
startInSec: null,
|
||||||
|
playlistLength: 86400.0,
|
||||||
configPlayout: [],
|
configPlayout: [],
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
configUser: null
|
configUser: null
|
||||||
@ -25,6 +27,12 @@ export const mutations = {
|
|||||||
UPDATE_NET_CHOICES (state, list) {
|
UPDATE_NET_CHOICES (state, list) {
|
||||||
state.netChoices = list
|
state.netChoices = list
|
||||||
},
|
},
|
||||||
|
UPDATE_START_TIME (state, sec) {
|
||||||
|
state.startInSec = sec
|
||||||
|
},
|
||||||
|
UPDATE_PLAYLIST_LENGTH (state, sec) {
|
||||||
|
state.playlistLength = sec
|
||||||
|
},
|
||||||
UPDATE_PLAYLOUT_CONFIG (state, config) {
|
UPDATE_PLAYLOUT_CONFIG (state, config) {
|
||||||
state.configPlayout = config
|
state.configPlayout = config
|
||||||
},
|
},
|
||||||
@ -103,6 +111,14 @@ export const actions = {
|
|||||||
const response = await this.$axios.get(`api/player/config/?configPlayout&path=${path}`)
|
const response = await this.$axios.get(`api/player/config/?configPlayout&path=${path}`)
|
||||||
|
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
|
if (response.data.playlist.day_start) {
|
||||||
|
commit('UPDATE_START_TIME', this.$timeToSeconds(response.data.playlist.day_start))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.data.playlist.length) {
|
||||||
|
commit('UPDATE_PLAYLIST_LENGTH', this.$timeToSeconds(response.data.playlist.length))
|
||||||
|
}
|
||||||
|
|
||||||
commit('UPDATE_PLAYLOUT_CONFIG', response.data)
|
commit('UPDATE_PLAYLOUT_CONFIG', response.data)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -49,15 +49,24 @@ export const mutations = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const actions = {
|
export const actions = {
|
||||||
async getPlaylist ({ commit, dispatch, state }, { dayStart, date }) {
|
async getPlaylist ({ commit, dispatch, state, rootState }, { dayStart, date }) {
|
||||||
|
const timeInSec = this.$timeToSeconds(this.$dayjs().format('HH:mm:ss'))
|
||||||
|
let dateToday = this.$dayjs().format('YYYY-MM-DD')
|
||||||
|
|
||||||
|
if (rootState.config.startInSec > timeInSec) {
|
||||||
|
dateToday = this.$dayjs(dateToday).subtract(1, 'day').format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
|
||||||
const response = await this.$axios.get(`api/player/playlist/?date=${date}`)
|
const response = await this.$axios.get(`api/player/playlist/?date=${date}`)
|
||||||
|
|
||||||
if (response.data && response.data.program) {
|
if (response.data && response.data.program) {
|
||||||
commit('UPDATE_PLAYLIST', this.$processPlaylist(dayStart, response.data.program))
|
commit('UPDATE_PLAYLIST', this.$processPlaylist(dayStart, response.data.program))
|
||||||
|
|
||||||
if (date === this.$dayjs().format('YYYY-MM-DD')) {
|
if (date === dateToday) {
|
||||||
commit('UPDATE_TODAYS_PLAYLIST', JSON.parse(JSON.stringify(response.data.program)))
|
commit('UPDATE_TODAYS_PLAYLIST', JSON.parse(JSON.stringify(response.data.program)))
|
||||||
dispatch('setCurrentClip')
|
dispatch('setCurrentClip')
|
||||||
|
} else {
|
||||||
|
commit('SET_CURRENT_CLIP_INDEX', null)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
commit('UPDATE_PLAYLIST', [])
|
commit('UPDATE_PLAYLIST', [])
|
||||||
@ -65,26 +74,30 @@ export const actions = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
setCurrentClip ({ commit, dispatch, state, rootState }) {
|
setCurrentClip ({ commit, dispatch, state, rootState }) {
|
||||||
let start
|
let begin
|
||||||
if (rootState.config.configPlayout.playlist.day_start) {
|
let lastTime = this.$timeToSeconds(this.$dayjs().format('HH:mm:ss'))
|
||||||
start = this.$timeToSeconds(rootState.config.configPlayout.playlist.day_start)
|
|
||||||
|
if (rootState.config.startInSec) {
|
||||||
|
begin = rootState.config.startInSec
|
||||||
} else {
|
} else {
|
||||||
commit('SET_CURRENT_CLIP', 'day_start is not set, cannot calculate current clip')
|
commit('SET_CURRENT_CLIP', 'day_start is not set, cannot calculate current clip')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lastTime < begin) {
|
||||||
|
lastTime += rootState.config.playlistLength
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < state.playlistToday.length; i++) {
|
for (let i = 0; i < state.playlistToday.length; i++) {
|
||||||
const duration = state.playlistToday[i].out - state.playlistToday[i].in
|
const duration = state.playlistToday[i].out - state.playlistToday[i].in
|
||||||
|
|
||||||
const playTime = this.$timeToSeconds(this.$dayjs().format('HH:mm:ss')) - start
|
|
||||||
|
|
||||||
// animate the progress bar
|
// animate the progress bar
|
||||||
if (playTime <= duration) {
|
if (lastTime < begin + duration) {
|
||||||
const progValue = playTime * 100 / duration
|
const progValue = (lastTime - begin) * 100 / duration
|
||||||
commit('SET_PROGRESS_VALUE', progValue)
|
commit('SET_PROGRESS_VALUE', progValue)
|
||||||
commit('SET_CURRENT_CLIP', state.playlistToday[i].source)
|
commit('SET_CURRENT_CLIP', state.playlistToday[i].source)
|
||||||
commit('SET_CURRENT_CLIP_INDEX', i)
|
commit('SET_CURRENT_CLIP_INDEX', i)
|
||||||
commit('SET_CURRENT_CLIP_START', start)
|
commit('SET_CURRENT_CLIP_START', begin)
|
||||||
commit('SET_CURRENT_CLIP_DURATION', duration)
|
commit('SET_CURRENT_CLIP_DURATION', duration)
|
||||||
commit('SET_CURRENT_CLIP_IN', state.playlistToday[i].in)
|
commit('SET_CURRENT_CLIP_IN', state.playlistToday[i].in)
|
||||||
commit('SET_CURRENT_CLIP_OUT', state.playlistToday[i].out)
|
commit('SET_CURRENT_CLIP_OUT', state.playlistToday[i].out)
|
||||||
@ -92,23 +105,28 @@ export const actions = {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
start += duration
|
begin += duration
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
animClock ({ commit, dispatch, state }) {
|
animClock ({ commit, dispatch, state, rootState }) {
|
||||||
const time = this.$dayjs().format('HH:mm:ss')
|
const time = this.$dayjs().format('HH:mm:ss')
|
||||||
const timeSec = this.$timeToSeconds(time)
|
let timeSec = this.$timeToSeconds(time)
|
||||||
const playTime = timeSec - state.currentClipStart
|
|
||||||
const progValue = playTime * 100 / state.currentClipDuration
|
|
||||||
|
|
||||||
commit('SET_TIME', time)
|
commit('SET_TIME', time)
|
||||||
|
|
||||||
|
if (timeSec < rootState.config.startInSec) {
|
||||||
|
timeSec += rootState.config.playlistLength
|
||||||
|
}
|
||||||
|
|
||||||
if (timeSec < state.currentClipStart) {
|
if (timeSec < state.currentClipStart) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// animate the progress bar
|
const playTime = timeSec - state.currentClipStart
|
||||||
|
const progValue = playTime * 100 / state.currentClipDuration
|
||||||
|
|
||||||
|
// set progress bar value
|
||||||
if (playTime <= state.currentClipDuration && progValue >= 0) {
|
if (playTime <= state.currentClipDuration && progValue >= 0) {
|
||||||
commit('SET_PROGRESS_VALUE', progValue)
|
commit('SET_PROGRESS_VALUE', progValue)
|
||||||
commit('SET_TIME_LEFT', this.$secToHMS(state.currentClipDuration - playTime))
|
commit('SET_TIME_LEFT', this.$secToHMS(state.currentClipDuration - playTime))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user