diff --git a/99-usb-automount.rules b/99-usb-automount.rules new file mode 100644 index 0000000..01280e9 --- /dev/null +++ b/99-usb-automount.rules @@ -0,0 +1,12 @@ +# USB Auto-Mount udev rules for Raspberry Pi Video Player +# These rules automatically mount USB devices when they are inserted + +# Mount USB storage devices when added +SUBSYSTEM=="block", KERNEL=="sd*[0-9]", ACTION=="add", RUN+="/opt/video_player/usb_automount.sh add %k" + +# Unmount USB storage devices when removed +SUBSYSTEM=="block", KERNEL=="sd*[0-9]", ACTION=="remove", RUN+="/opt/video_player/usb_automount.sh remove %k" + +# Alternative rules for different USB device naming patterns +SUBSYSTEM=="block", KERNEL=="mmcblk*[0-9]", ACTION=="add", RUN+="/opt/video_player/usb_automount.sh add %k" +SUBSYSTEM=="block", KERNEL=="mmcblk*[0-9]", ACTION=="remove", RUN+="/opt/video_player/usb_automount.sh remove %k" diff --git a/install.sh b/install.sh index 44c9e85..0c27d9d 100755 --- a/install.sh +++ b/install.sh @@ -75,7 +75,6 @@ install_packages() { python3-venv \ vlc \ vlc-plugin-base \ - vlc-plugin-video-output \ ffmpeg \ git \ curl \ @@ -98,16 +97,6 @@ install_packages() { libatlas-base-dev \ gfortran \ libhdf5-dev \ - libhdf5-103 \ - python3-pyqt5 \ - python3-pyqt5.qtwidgets \ - python3-pyqt5.qtgui \ - python3-pyqt5.qtcore \ - libgtk-3-dev \ - libcanberra-gtk3-module \ - libcanberra-gtk3-dev \ - libcanberra-gtk-dev \ - libcanberra-dev \ pulseaudio \ pulseaudio-utils \ alsa-utils \ @@ -118,7 +107,6 @@ install_packages() { python3-smbus \ python3-spidev \ python3-pil \ - python3-pil.imagetk \ python3-setuptools \ python3-wheel @@ -179,8 +167,13 @@ copy_files() { cp ir_remote.py "$INSTALL_DIR/" cp config_manager.py "$INSTALL_DIR/" - # Copy service file + # Copy USB auto-mount script + cp usb_automount.sh "$INSTALL_DIR/" + chmod +x "$INSTALL_DIR/usb_automount.sh" + + # Copy service files cp video-player.service /etc/systemd/system/ + cp usb-automount.service /etc/systemd/system/ # Copy configuration templates mkdir -p "$CONFIG_DIR/templates" @@ -335,6 +328,30 @@ EOF print_success "Default configuration created" } +# Function to setup USB auto-mounting +setup_usb_automount() { + print_status "Setting up USB auto-mounting..." + + # Create USB mount directory + mkdir -p /media/usb + chown "$USER:$USER" /media/usb + chmod 755 /media/usb + + # Copy udev rules + cp 99-usb-automount.rules /etc/udev/rules.d/ + chmod 644 /etc/udev/rules.d/99-usb-automount.rules + + # Reload udev rules + udevadm control --reload-rules + udevadm trigger + + # Enable USB auto-mount service + systemctl daemon-reload + systemctl enable usb-automount + + print_success "USB auto-mounting configured" +} + # Function to setup GPIO permissions setup_gpio_permissions() { print_status "Setting up GPIO permissions..." @@ -449,6 +466,12 @@ EOF cat > /usr/local/bin/video-player-logs << 'EOF' #!/bin/bash sudo journalctl -u video-player -f +EOF + + # Create USB management script + cat > /usr/local/bin/video-player-usb << 'EOF' +#!/bin/bash +/opt/video_player/usb_automount.sh "$@" EOF # Set permissions @@ -475,13 +498,15 @@ display_summary() { echo "Restart: video-player-restart" echo "Status: video-player-status" echo "Logs: video-player-logs" + echo "USB: video-player-usb {scan|mount-all}" echo echo "Next Steps:" echo "===========" echo "1. Add video files to: $VIDEO_FOLDER" - echo "2. Configure IR remote codes in: $CONFIG_DIR/ir_mapping.json" - echo "3. Start the service: video-player-start" - echo "4. Check status: video-player-status" + echo "2. Insert USB drives - they will auto-mount to: /media/usb/" + echo "3. Configure IR remote codes in: $CONFIG_DIR/ir_mapping.json" + echo "4. Start the service: video-player-start" + echo "5. Check status: video-player-status" echo echo "For more information, see the documentation in $INSTALL_DIR" } @@ -503,6 +528,7 @@ main() { create_directories copy_files create_default_config + setup_usb_automount setup_gpio_permissions setup_service create_sample_video diff --git a/usb-automount.service b/usb-automount.service new file mode 100644 index 0000000..8b5e4bd --- /dev/null +++ b/usb-automount.service @@ -0,0 +1,15 @@ +[Unit] +Description=USB Auto-Mount Service for Video Player +After=multi-user.target +Wants=multi-user.target + +[Service] +Type=oneshot +ExecStart=/opt/video_player/usb_automount.sh mount-all +RemainAfterExit=yes +User=root +StandardOutput=journal +StandardError=journal + +[Install] +WantedBy=multi-user.target diff --git a/usb_automount.sh b/usb_automount.sh new file mode 100755 index 0000000..ceb52fc --- /dev/null +++ b/usb_automount.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# USB Auto-Mount Script for Raspberry Pi Video Player +# This script automatically mounts USB devices when they are inserted + +# Configuration +MOUNT_BASE="/media/usb" +LOG_FILE="/var/log/usb_automount.log" +USER="pi" + +# Function to log messages +log_message() { + echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" +} + +# Function to create mount point +create_mount_point() { + local device_name="$1" + local mount_point="$MOUNT_BASE/$device_name" + + if [ ! -d "$mount_point" ]; then + mkdir -p "$mount_point" + chown "$USER:$USER" "$mount_point" + log_message "Created mount point: $mount_point" + fi +} + +# Function to mount USB device +mount_usb_device() { + local device_path="$1" + local device_name=$(basename "$device_path") + local mount_point="$MOUNT_BASE/$device_name" + + # Check if device is already mounted + if mountpoint -q "$mount_point" 2>/dev/null; then + log_message "Device $device_name is already mounted at $mount_point" + return 0 + fi + + # Create mount point + create_mount_point "$device_name" + + # Get device label (if available) + local label=$(blkid -s LABEL -o value "$device_path" 2>/dev/null) + if [ -n "$label" ]; then + # Use label as mount point name if available + mount_point="$MOUNT_BASE/$label" + create_mount_point "$label" + fi + + # Mount the device + if mount -o uid=1000,gid=1000,umask=0002 "$device_path" "$mount_point" 2>/dev/null; then + log_message "Successfully mounted $device_name at $mount_point" + + # Create symlink for easy access + ln -sf "$mount_point" "/home/$USER/Desktop/USB-$device_name" 2>/dev/null || true + + # Notify user (if desktop environment is running) + if [ -n "$DISPLAY" ]; then + notify-send "USB Device Mounted" "Device $device_name mounted at $mount_point" 2>/dev/null || true + fi + + return 0 + else + log_message "Failed to mount $device_name at $mount_point" + return 1 + fi +} + +# Function to unmount USB device +unmount_usb_device() { + local device_path="$1" + local device_name=$(basename "$device_path") + + # Find mount point + local mount_point=$(mount | grep "$device_path" | awk '{print $3}') + + if [ -n "$mount_point" ]; then + if umount "$mount_point" 2>/dev/null; then + log_message "Successfully unmounted $device_name from $mount_point" + + # Remove symlink + rm -f "/home/$USER/Desktop/USB-$device_name" 2>/dev/null || true + + # Remove mount point if empty + if [ -d "$mount_point" ] && [ -z "$(ls -A "$mount_point" 2>/dev/null)" ]; then + rmdir "$mount_point" 2>/dev/null || true + fi + + # Notify user + if [ -n "$DISPLAY" ]; then + notify-send "USB Device Unmounted" "Device $device_name has been unmounted" 2>/dev/null || true + fi + + return 0 + else + log_message "Failed to unmount $device_name from $mount_point" + return 1 + fi + else + log_message "Device $device_name is not mounted" + return 1 + fi +} + +# Function to mount all existing USB devices +mount_existing_devices() { + log_message "Checking for existing USB devices..." + + # Find all USB block devices + for device in /dev/sd*[0-9]; do + if [ -b "$device" ]; then + # Check if it's a USB device + if readlink -f "$device" | grep -q "usb"; then + mount_usb_device "$device" + fi + fi + done +} + +# Function to scan for video files on mounted USB devices +scan_usb_videos() { + log_message "Scanning USB devices for video files..." + + local video_extensions="mp4|avi|mkv|mov|wmv|flv|webm|m4v" + local video_count=0 + + for mount_point in "$MOUNT_BASE"/*; do + if [ -d "$mount_point" ] && mountpoint -q "$mount_point" 2>/dev/null; then + local videos=$(find "$mount_point" -type f -iregex ".*\.\($video_extensions\)" 2>/dev/null | wc -l) + if [ "$videos" -gt 0 ]; then + log_message "Found $videos video files on $(basename "$mount_point")" + video_count=$((video_count + videos)) + fi + fi + done + + log_message "Total video files found on USB devices: $video_count" +} + +# Main function +main() { + case "$1" in + "add") + if [ -n "$2" ]; then + mount_usb_device "$2" + else + echo "Usage: $0 add " + exit 1 + fi + ;; + "remove") + if [ -n "$2" ]; then + unmount_usb_device "$2" + else + echo "Usage: $0 remove " + exit 1 + fi + ;; + "scan") + scan_usb_videos + ;; + "mount-all") + mount_existing_devices + ;; + *) + echo "Usage: $0 {add|remove|scan|mount-all} [device_path]" + echo " add - Mount a USB device" + echo " remove - Unmount a USB device" + echo " scan - Scan for video files on mounted USB devices" + echo " mount-all - Mount all existing USB devices" + exit 1 + ;; + esac +} + +# Create necessary directories +mkdir -p "$MOUNT_BASE" +mkdir -p "$(dirname "$LOG_FILE")" + +# Run main function with all arguments +main "$@"