urmi_downloader_converter/transcode.sh

311 lines
11 KiB
Bash
Executable File

#!/bin/bash
echo "Transcoding service started..."
# Configuration
QUEUE_DIR="/var/www/html/download/queue"
READY_DIR="/var/www/html/download/ready"
SETTINGS_FILE="/var/www/html/settings/settings.json"
LOG_FILE="/var/log/convert.log"
LOGO_FILE="/var/www/html/settings/logo.png"
# Create directories if they don't exist
mkdir -p "$QUEUE_DIR"
mkdir -p "$READY_DIR"
# Load settings from JSON file
load_settings() {
VIDEO_FORMAT=$(jq -r '.video_format' "$SETTINGS_FILE")
AUDIO_FORMAT=$(jq -r '.audio_format' "$SETTINGS_FILE")
VIDEO_BITRATE=$(jq -r '.video_bitrate' "$SETTINGS_FILE")
AUDIO_BITRATE=$(jq -r '.audio_bitrate' "$SETTINGS_FILE")
RESOLUTION=$(jq -r '.resolution' "$SETTINGS_FILE")
FRAME_RATE=$(jq -r '.frame_rate' "$SETTINGS_FILE")
GOP=$(jq -r '.gop' "$SETTINGS_FILE")
}
# Function to sanitize filename
sanitize_filename() {
local filename="$1"
# Remove special characters, keep only a-z, A-Z, 0-9, and .
local sanitized=$(echo "$filename" | sed 's/[^a-zA-Z0-9.]*//g')
# If filename starts with number, add prefix
if [[ "$sanitized" =~ ^[0-9] ]]; then
sanitized="dev_${sanitized}"
fi
# If filename is empty after sanitization, use timestamp
if [[ -z "$sanitized" ]]; then
sanitized="dev_$(date +%s)"
fi
echo "$sanitized"
}
# Function to get video resolution
get_video_resolution() {
local input_file="$1"
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "$input_file"
}
# Function to calculate logo size based on video resolution
calculate_logo_size() {
local video_width="$1"
local video_height="$2"
# Calculate 10% of video width/height for logo size
local logo_width=$((video_width / 10))
local logo_height=$((video_height / 10))
# Ensure minimum size of 64x64
if [ "$logo_width" -lt 64 ]; then logo_width=64; fi
if [ "$logo_height" -lt 64 ]; then logo_height=64; fi
# Ensure maximum size of 128x128
if [ "$logo_width" -gt 128 ]; then logo_width=128; fi
if [ "$logo_height" -gt 128 ]; then logo_height=128; fi
echo "${logo_width}x${logo_height}"
}
# Main processing loop
while true; do
# Load settings at start of each loop
load_settings
# Find all files in queue directory
for file in "$QUEUE_DIR"/*; do
# Skip if no files found
[ -f "$file" ] || continue
# Get original filename
original_name=$(basename "$file")
# Sanitize filename
sanitized_name=$(sanitize_filename "$original_name")
# Add .ts extension
sanitized_name="${sanitized_name}.ts"
# Set output path
output_file="$READY_DIR/$sanitized_name"
# Check if logo file exists
if [ -f "$LOGO_FILE" ]; then
# Get video resolution
video_res=$(get_video_resolution "$file")
video_width=$(echo "$video_res" | cut -d'x' -f1)
video_height=$(echo "$video_res" | cut -d'x' -f2)
# Calculate logo size
logo_size=$(calculate_logo_size "$video_width" "$video_height")
# STB compatible encoding based on video format
if [ "$VIDEO_FORMAT" = "mpeg2video" ]; then
# MPEG2 settings for STB compatibility
ffmpeg \
-i "$file" \
-i "$LOGO_FILE" \
-filter_complex "\
[0:v]scale=${RESOLUTION}[v];\
[1:v]scale=${logo_size}[logo];\
[v][logo]overlay=W-w-20:20" \
-c:v mpeg2video \
-b:v "$VIDEO_BITRATE" \
-bt "$VIDEO_BITRATE" \
-maxrate "$VIDEO_BITRATE" \
-bufsize "$VIDEO_BITRATE" \
-flags +global_header \
-profile:v 2 \
-level:v 4 \
-c:a "$AUDIO_FORMAT" \
-b:a "$AUDIO_BITRATE" \
-ab "$AUDIO_BITRATE" \
-r "$FRAME_RATE" \
-g "$GOP" \
-f mpegts "$output_file" \
2>>"$LOG_FILE"
elif [ "$VIDEO_FORMAT" = "libx264" ]; then
# H.264 settings for STB compatibility
ffmpeg \
-i "$file" \
-i "$LOGO_FILE" \
-filter_complex "\
[0:v]scale=${RESOLUTION}[v];\
[1:v]scale=${logo_size}[logo];\
[v][logo]overlay=W-w-20:20" \
-c:v libx264 \
-b:v "$VIDEO_BITRATE" \
-bt "$VIDEO_BITRATE" \
-maxrate "$VIDEO_BITRATE" \
-bufsize "$VIDEO_BITRATE" \
-preset fast \
-profile:v baseline \
-level 3.0 \
-flags +global_header \
-c:a "$AUDIO_FORMAT" \
-b:a "$AUDIO_BITRATE" \
-ab "$AUDIO_BITRATE" \
-r "$FRAME_RATE" \
-g "$GOP" \
-f mpegts "$output_file" \
2>>"$LOG_FILE"
elif [ "$VIDEO_FORMAT" = "libx265" ]; then
# H.265 settings for STB compatibility
ffmpeg \
-i "$file" \
-i "$LOGO_FILE" \
-filter_complex "\
[0:v]scale=${RESOLUTION}[v];\
[1:v]scale=${logo_size}[logo];\
[v][logo]overlay=W-w-20:20" \
-c:v libx265 \
-b:v "$VIDEO_BITRATE" \
-bt "$VIDEO_BITRATE" \
-maxrate "$VIDEO_BITRATE" \
-bufsize "$VIDEO_BITRATE" \
-preset fast \
-profile:v main \
-level 3.0 \
-flags +global_header \
-c:a "$AUDIO_FORMAT" \
-b:a "$AUDIO_BITRATE" \
-ab "$AUDIO_BITRATE" \
-r "$FRAME_RATE" \
-g "$GOP" \
-f mpegts "$output_file" \
2>>"$LOG_FILE"
else
# Default fallback to MPEG2
ffmpeg \
-i "$file" \
-i "$LOGO_FILE" \
-filter_complex "\
[0:v]scale=${RESOLUTION}[v];\
[1:v]scale=${logo_size}[logo];\
[v][logo]overlay=W-w-20:20" \
-c:v mpeg2video \
-b:v "$VIDEO_BITRATE" \
-bt "$VIDEO_BITRATE" \
-maxrate "$VIDEO_BITRATE" \
-bufsize "$VIDEO_BITRATE" \
-flags +global_header \
-profile:v 2 \
-level:v 4 \
-c:a "$AUDIO_FORMAT" \
-b:a "$AUDIO_BITRATE" \
-ab "$AUDIO_BITRATE" \
-r "$FRAME_RATE" \
-g "$GOP" \
-f mpegts "$output_file" \
2>>"$LOG_FILE"
fi
# Check if conversion was successful
if [ $? -eq 0 ]; then
rm "$file"
echo "$(date): Successfully converted $original_name to $sanitized_name" >> "$LOG_FILE"
else
# If conversion failed, log error
echo "$(date): Failed to convert $original_name" >> "$LOG_FILE"
fi
else
# STB compatible encoding without logo
if [ "$VIDEO_FORMAT" = "mpeg2video" ]; then
# MPEG2 settings for STB compatibility
ffmpeg \
-i "$file" \
-c:v mpeg2video \
-b:v "$VIDEO_BITRATE" \
-bt "$VIDEO_BITRATE" \
-maxrate "$VIDEO_BITRATE" \
-bufsize "$VIDEO_BITRATE" \
-flags +global_header \
-profile:v 2 \
-level:v 4 \
-c:a "$AUDIO_FORMAT" \
-b:a "$AUDIO_BITRATE" \
-ab "$AUDIO_BITRATE" \
-s "$RESOLUTION" \
-r "$FRAME_RATE" \
-g "$GOP" \
-f mpegts "$output_file" \
2>>"$LOG_FILE"
elif [ "$VIDEO_FORMAT" = "libx264" ]; then
# H.264 settings for STB compatibility
ffmpeg \
-i "$file" \
-c:v libx264 \
-b:v "$VIDEO_BITRATE" \
-bt "$VIDEO_BITRATE" \
-maxrate "$VIDEO_BITRATE" \
-bufsize "$VIDEO_BITRATE" \
-preset fast \
-profile:v baseline \
-level 3.0 \
-flags +global_header \
-c:a "$AUDIO_FORMAT" \
-b:a "$AUDIO_BITRATE" \
-ab "$AUDIO_BITRATE" \
-s "$RESOLUTION" \
-r "$FRAME_RATE" \
-g "$GOP" \
-f mpegts "$output_file" \
2>>"$LOG_FILE"
elif [ "$VIDEO_FORMAT" = "libx265" ]; then
# H.265 settings for STB compatibility
ffmpeg \
-i "$file" \
-c:v libx265 \
-b:v "$VIDEO_BITRATE" \
-bt "$VIDEO_BITRATE" \
-maxrate "$VIDEO_BITRATE" \
-bufsize "$VIDEO_BITRATE" \
-preset fast \
-profile:v main \
-level 3.0 \
-flags +global_header \
-c:a "$AUDIO_FORMAT" \
-b:a "$AUDIO_BITRATE" \
-ab "$AUDIO_BITRATE" \
-s "$RESOLUTION" \
-r "$FRAME_RATE" \
-g "$GOP" \
-f mpegts "$output_file" \
2>>"$LOG_FILE"
else
# Default fallback to MPEG2
ffmpeg \
-i "$file" \
-c:v mpeg2video \
-b:v "$VIDEO_BITRATE" \
-bt "$VIDEO_BITRATE" \
-maxrate "$VIDEO_BITRATE" \
-bufsize "$VIDEO_BITRATE" \
-flags +global_header \
-profile:v 2 \
-level:v 4 \
-c:a "$AUDIO_FORMAT" \
-b:a "$AUDIO_BITRATE" \
-ab "$AUDIO_BITRATE" \
-s "$RESOLUTION" \
-r "$FRAME_RATE" \
-g "$GOP" \
-f mpegts "$output_file" \
2>>"$LOG_FILE"
fi
# Check if conversion was successful
if [ $? -eq 0 ]; then
rm "$file"
echo "$(date): Successfully converted $original_name to $sanitized_name" >> "$LOG_FILE"
else
# If conversion failed, log error
echo "$(date): Failed to convert $original_name" >> "$LOG_FILE"
fi
fi
done
# Wait before checking for new files
sleep 60
done