├── README.md ├── run_ffmpeg.sh ├── start_serveo.sh ├── start_streaming.sh ├── stop_services.sh ├── stream_config.conf ├── template.html └── update_html.sh /README.md: -------------------------------------------------------------------------------- 1 | # RTSP2HTTP 2 | This project is intended to convert RTSP streams to HTTP. 3 | 4 | *If you detect any bug/problem using the script, open an issue on Github and explain the steps where it happened and how, so I can reproduce and fix them.* 5 | 6 | 7 | 8 | 9 | ## Installation 10 | 11 | Install requirements to use RTSP2HTTP: 12 | 13 | XAMPP (make sure the installation goes to /opt/lampp/): 14 | 15 | https://www.apachefriends.org/index.html 16 | 17 | (Guide for installation): 18 | 19 | https://smarttech101.com/how-to-install-and-manage-xampp-in-linux/ 20 | 21 | *XAMPP will be replaced with LAMP in future updates, but for now, use XAMPP.* 22 | 23 | FFMPEG: 24 | ```bash 25 | sudo apt-get update && sudo apt-get install -y ffmpeg 26 | ``` 27 | 28 | SSH: 29 | ```bash 30 | sudo apt-get update && sudo apt-get install -y ssh 31 | ``` 32 | Git: 33 | *(Optional, you can download the files from this repo without git)* 34 | ```bash 35 | sudo apt-get update && sudo apt-get install -y git 36 | ``` 37 | ## Setup 38 | 39 | 1. Repository Files Preparation: 40 | 41 | *Ensure all the necessary files from the repository are located in the /opt/lampp/htdocs/ directory. This is crucial for the proper functioning of the project.* 42 | 43 | ```bash 44 | sudo git clone --branch beta-1 https://github.com/nullvoid413/RTSP2HTTP /opt/lampp/htdocs/ 45 | ``` 46 | 47 | 2. Set Executable Permissions: 48 | 49 | *Open your terminal and run the following command to grant executable permissions to all files in the /opt/lampp/htdocs/ directory:* 50 | ```bash 51 | sudo chmod +x /opt/lampp/htdocs/* 52 | ``` 53 | 54 | 3. Navigate to Project Directory: 55 | 56 | *Change your current working directory to the project folder by executing:* 57 | ```bash 58 | cd /opt/lampp/htdocs 59 | ``` 60 | 61 | 4. Configure Camera Streams: 62 | 63 | *Input the RTSP link for each of your cameras. Remember, each line in this file corresponds to one camera. To configure multiple cameras, simply add more lines with their respective RTSP links.* 64 | ```bash 65 | Edit the stream_config.conf file that you downloaded from this Repo which is located in /opt/lampp/htdocs/ directory. 66 | ``` 67 | 68 | 5. Initiate Streaming Process: 69 | 70 | *Start the streaming process by running the start_streaming.sh script. Execute this command:* 71 | ```bash 72 | sudo ./start_streaming.sh 73 | ``` 74 | 75 | 6. Project Loading: 76 | *Please allow some time for the project to initialize and load correctly. This might take a few moments depending on your system specifications and the number of camera streams.* 77 | 78 | Additional Notes: 79 | 80 | *Ensure that your system meets all the necessary prerequisites for running the project. 81 | For any troubleshooting or additional configurations, refer to the project's documentation or contact support. 82 | By following these steps, you should be able to successfully set up and enjoy the Camera Streaming. 83 | For further assistance or inquiries, please do not hesitate to reach out.* 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /run_ffmpeg.sh: -------------------------------------------------------------------------------- 1 | 2 | # Function to handle cleanup actions 3 | cleanup() { 4 | # Deleting .m3u8, .ts files, and log files in the video directory 5 | find /var/www/html -type f -name '*.m3u8' -delete 6 | find /var/www/html -type f -name '*.ts' -delete 7 | find /var/www/html -type f -name '*.log' -delete 8 | # Add more file types here if needed 9 | echo "Cleanup completed." 10 | } 11 | 12 | # Trap signals and call the cleanup function when any of these signals are received 13 | trap 'cleanup' SIGINT SIGTERM EXIT 14 | #!/bin/bash 15 | 16 | # Path to the configuration file 17 | config_file="/var/www/html/stream_config.conf" 18 | 19 | # Path to the HTML template 20 | html_template="/var/www/html/template.html" 21 | 22 | # Directory containing the HTML files 23 | html_directory="/var/www/html" 24 | video_directory="/var/www/html" # Update with the path where .ts video files are generated 25 | metadata_file="/var/www/html/camera_metadata.json" 26 | 27 | # Function to start an ffmpeg stream 28 | start_ffmpeg_stream() { 29 | local url=$1 30 | local stream_number=$2 31 | local output_file="/var/www/html/stream$stream_number.m3u8" # Changed file extension to .m3u8 32 | local thumbnail_file="/var/www/html/camera${stream_number}.jpg" 33 | 34 | # Start ffmpeg to generate the stream and m3u8 file 35 | sudo ffmpeg -rtsp_transport tcp -i "$url" -c:v copy -c:a copy -f hls -hls_time 2 -hls_list_size 3 -hls_flags delete_segments -hls_segment_filename "/var/www/html/stream${stream_number}-%03d.ts" "$output_file" 2> "${output_file}.log" & 36 | 37 | # Generate a thumbnail for the stream 38 | generate_thumbnail "$output_file" "$thumbnail_file" 39 | 40 | # Add camera metadata to the metadata file 41 | echo "{\"camera\": $stream_number, \"video_file\": \"stream$stream_number.m3u8\"}" >> "$metadata_file" 42 | 43 | # Generate thumbnails and camera links for index.html 44 | generate_html_content "$stream_number" "$thumbnail_file" 45 | } 46 | 47 | # Function to generate a thumbnail for a video file 48 | generate_thumbnail() { 49 | local video_file="$1" 50 | local thumbnail_file="$2" 51 | 52 | # Use ffmpeg to generate the thumbnail 53 | if ffmpeg -i "$video_file" -vf "thumbnail,scale=150:150" -frames:v 1 -update 1 "$thumbnail_file" -y; then 54 | echo "Thumbnail generated for $video_file" 55 | else 56 | echo "Error generating thumbnail for $video_file" 57 | fi 58 | } 59 | 60 | # Function to create an HTML file for each stream 61 | create_html_file() { 62 | local stream_number=$1 63 | local html_file="$html_directory/camera${stream_number}.html" 64 | cp "$html_template" "$html_file" 65 | } 66 | 67 | # Function to generate HTML content for index.html 68 | generate_html_content() { 69 | local stream_number=$1 70 | local thumbnail_file="$2" 71 | 72 | cat >> "$html_directory/index.html" < 74 | 75 | Camera $stream_number Thumbnail 76 | 77 | Camera $stream_number 78 | 79 | EOF 80 | } 81 | 82 | # Remove the existing metadata file 83 | rm -f "$metadata_file" 84 | 85 | # Create or overwrite index.html with the initial HTML structure 86 | cat > "$html_directory/index.html" < 88 | 89 | 90 | 91 | 92 | Camera Thumbnails 93 | 134 | 135 | 136 | EOF 137 | 138 | # Read each URL from the configuration file, start a stream, and create an HTML file 139 | i=1 140 | while IFS= read -r url; do 141 | if [ -n "$url" ]; then 142 | start_ffmpeg_stream "$url" "$i" 143 | create_html_file "$i" 144 | ((i++)) 145 | fi 146 | done < "$config_file" 147 | 148 | # Wait for a moment to allow ffmpeg processes to start 149 | sleep 5 150 | 151 | # Check each ffmpeg process for errors 152 | for j in $(seq 1 $i); do 153 | if grep -q 'error' "$html_directory/stream${j}.m3u8.log"; then 154 | echo "ffmpeg for stream${j} encountered an error." 155 | else 156 | echo "ffmpeg for stream${j} is running." 157 | fi 158 | done 159 | 160 | # Close the index.html file 161 | echo "" >> "$html_directory/index.html" 162 | -------------------------------------------------------------------------------- /start_serveo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Define the output file in the current directory 4 | output_file="serveo_output.txt" 5 | url_file="/var/www/html/current_serveo_url.txt" # File to store the current Serveo URL 6 | 7 | # Start Serveo SSH tunnel in the background and redirect output to the output file 8 | sudo ssh -tt -R 80:localhost:80 serveo.net > "$output_file" 2>&1 & 9 | ssh_pid=$! 10 | 11 | # Timeout for checking the Serveo URL 12 | timeout=30 13 | 14 | # Initialize a variable to store the Serveo URL 15 | serveo_url="" 16 | 17 | # Function to extract and print Serveo URL 18 | get_serveo_url() { 19 | local url_pattern="https?://\S+\.serveo\.net" 20 | local found_url 21 | found_url=$(grep -oP "$url_pattern" "$output_file" | head -1) 22 | if [ -n "$found_url" ]; then 23 | serveo_url="$found_url" 24 | echo "Serveo URL: $serveo_url" 25 | return 0 26 | else 27 | return 1 28 | fi 29 | } 30 | 31 | # Loop to check the output file for the Serveo URL 32 | while [ $timeout -gt 0 ]; do 33 | if get_serveo_url; then 34 | > "$output_file" 35 | break 36 | fi 37 | sleep 1 38 | ((timeout--)) 39 | done 40 | 41 | # If URL not found in specified time, kill SSH process 42 | if [ -z "$serveo_url" ]; then 43 | echo "Serveo URL not found within the expected time." 44 | sudo kill $ssh_pid 45 | exit 1 46 | fi 47 | 48 | # Compare with the previous URL and update HTML files if different 49 | if [ -f "$url_file" ]; then 50 | previous_url=$(cat "$url_file") 51 | if [ "$serveo_url" != "$previous_url" ]; then 52 | sudo ./update_html.sh "$serveo_url" 53 | fi 54 | else 55 | sudo ./update_html.sh "$serveo_url" # First time setup or URL file not found 56 | fi 57 | 58 | # Update the URL file with the current URL 59 | echo "$serveo_url" > "$url_file" 60 | 61 | # Display the Serveo URL in a Zenity text entry dialog 62 | echo "Serveo URL: $serveo_url" 63 | 64 | # Cleanup: Optionally remove the output file 65 | rm "$output_file" 66 | -------------------------------------------------------------------------------- /start_streaming.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sed -i "s|var streamUrl = '.*';|var streamUrl = 'REPLACE_WITH_STREAM_URL';|" "/var/www/html/template.html" 3 | 4 | # Function to check if a command exists 5 | command_exists() { 6 | type "$1" &> /dev/null 7 | } 8 | 9 | # Function to handle cleanup actions 10 | cleanup() { 11 | # Restore the placeholder value in template.html 12 | sed -i "s|var streamUrl = '.*';|var streamUrl = 'REPLACE_WITH_STREAM_URL';|" "/var/www/html/template.html" 13 | 14 | # Delete all files except the ones listed 15 | find /var/www/html -type f | grep -vE '(start_streaming\.sh|run_ffmpeg\.sh|start_serveo\.sh|stop_services\.sh|stream_config\.conf|template\.html|update_html\.sh)' | xargs rm 16 | 17 | # Stop services (you can add your service stopping logic here) 18 | sudo /var/www/html/stop_services.sh 19 | 20 | exit 0 21 | } 22 | 23 | # Trap signals and call the cleanup function when any of these signals are received 24 | trap 'cleanup' SIGINT SIGTERM SIGHUP 25 | 26 | # Check for ffmpeg 27 | if command_exists ffmpeg; then 28 | echo "ffmpeg is installed." 29 | else 30 | echo "ffmpeg is not installed. Installing ffmpeg..." 31 | sudo apt-get update && sudo apt-get install -y ffmpeg 32 | fi 33 | 34 | # Check for ssh 35 | if command_exists ssh; then 36 | echo "ssh is installed." 37 | else 38 | echo "ssh is not installed. Installing ssh..." 39 | sudo apt-get update && sudo apt-get install -y ssh 40 | fi 41 | 42 | if systemctl is-active --quiet apache2; then 43 | echo "Apache2 is running." 44 | else 45 | echo "Apache2 is not running. Attempting to start Apache2..." 46 | sudo systemctl start apache2 47 | if [ $? -eq 0 ]; then 48 | echo "Apache2 started successfully." 49 | else 50 | echo "Failed to start Apache2. Please check the installation or try starting it manually." 51 | exit 1 52 | fi 53 | fi 54 | 55 | 56 | # If all dependencies are satisfied, continue with the script 57 | 58 | # Run ffmpeg in the background and log its output 59 | echo "Starting ffmpeg..." 60 | sudo /var/www/html/run_ffmpeg.sh > /var/www/html/ffmpeg.log 2>&1 & 61 | 62 | # Run Serveo in the background and log its output 63 | echo "Starting Serveo..." 64 | sudo /var/www/html/start_serveo.sh > /var/www/html/serveo.log 2>&1 & 65 | 66 | sleep 10 67 | serveo_url=$(cat /var/www/html/current_serveo_url.txt) 68 | echo "Serveo URL: $serveo_url" 69 | 70 | # Ask the user if they want to stop services 71 | echo "Services are running. Do you want to stop them? (y/n): " 72 | read stop_answer 73 | if [ "$stop_answer" = "y" ]; then 74 | cleanup 75 | fi 76 | -------------------------------------------------------------------------------- /stop_services.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Function to check if a service is running 4 | is_service_running() { 5 | pgrep -f "$1" > /dev/null 6 | return $? 7 | } 8 | 9 | # Function to stop a service 10 | stop_service() { 11 | pkill -f "$1" 12 | } 13 | 14 | # Initialize variable to store names of running services 15 | running_services="" 16 | 17 | # Check if ffmpeg is running 18 | is_service_running "ffmpeg" 19 | if [ $? -eq 0 ]; then 20 | running_services+="ffmpeg " 21 | fi 22 | 23 | # Check if XAMPP's Apache is running 24 | is_service_running "apache2" 25 | if [ $? -eq 0 ]; then 26 | running_services+="apache2 " 27 | fi 28 | 29 | # Check if SSH is running 30 | is_service_running "ssh" 31 | if [ $? -eq 0 ]; then 32 | running_services+="ssh " 33 | fi 34 | 35 | # Check if any services are running 36 | if [ ! -z "$running_services" ]; then 37 | echo "The following services are running: $running_services" 38 | echo "Do you want to stop these services? (y/n): " 39 | read stop_all_answer 40 | if [ "$stop_all_answer" = "y" ]; then 41 | # Stop each running service 42 | for service in $running_services; do 43 | stop_service "$service" 44 | echo "$service stopped." 45 | done 46 | 47 | # Ask if the user wants to start streaming again 48 | echo "Do you want to start streaming again? (y/n): " 49 | read start_streaming_answer 50 | if [ "$start_streaming_answer" = "y" ]; then 51 | sudo ./start_streaming.sh 52 | fi 53 | fi 54 | else 55 | echo "No services are currently running." 56 | fi 57 | 58 | echo "Service stopping process completed." 59 | -------------------------------------------------------------------------------- /stream_config.conf: -------------------------------------------------------------------------------- 1 | rtsp://user:pass@IP:554/stream1 2 | -------------------------------------------------------------------------------- /template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Live Streaming 6 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /update_html.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The Serveo domain passed from the start_serveo.sh script 4 | serveo_domain=$1 5 | 6 | # Directory containing the HTML files 7 | html_directory="/var/www/html" 8 | 9 | # Loop through each generated HTML file in the directory (excluding template.html) 10 | for html_file in "$html_directory"/camera*.html; do 11 | # Check if HTML file exists 12 | if [ ! -f "$html_file" ]; then 13 | echo "Skipping, not a file: $html_file" 14 | continue 15 | fi 16 | 17 | # Check if the file is "template.html" and skip it 18 | if [ "$(basename "$html_file")" = "template.html" ]; then 19 | echo "Skipping, it's template.html: $html_file" 20 | continue 21 | fi 22 | 23 | # Extract the camera number from the filename (assuming format camera[number].html) 24 | camera_number=$(echo "$html_file" | grep -oP 'camera\K[0-9]+') 25 | 26 | # Construct new Serveo stream URL with the camera number 27 | new_url="${serveo_domain}/stream${camera_number}.m3u8" 28 | 29 | # Use sed to replace the placeholder with the new Serveo URL 30 | sed -i "s|REPLACE_WITH_STREAM_URL|${new_url}|" "$html_file" 31 | 32 | echo "HTML file successfully updated: $html_file" 33 | done 34 | 35 | # Update the template.html separately with a generic placeholder URL 36 | sed -i "s|REPLACE_WITH_STREAM_URL|${serveo_domain}/streamX.m3u8|" "$html_directory/template.html" 37 | --------------------------------------------------------------------------------