需求:
首先需要树莓派自动挂载USB设备,然后扫描USB指定目录下文件,将相关文件拷贝至树莓派指定目录,然后通过omxplayer循环播放新拷贝文件视频


1. 树莓派实现USB存储设备自动挂载

树莓派USB存储设备自动挂载
udev 实现 USB 设备自动挂载

需要注意的是:
必须使用pi用户登陆至图形界面(图形界面默认是开启移动设备自动挂载的),否则会挂载不成功,如果使用其他用户登录,系统界面会看到挂载失败的错误信息;通过上面的方法设置也不成功,最后都必须通过pi用户登录到图形界面。
上面的方法根本不可在命令行下实现USB设备的自动挂载。

2. 树莓派安装omxplayer

Raspberry pi音乐播放器omxplayer
轻松搞定omxplayer操作界面安装

3. Shell脚本实现文件自动拷贝并调用omxplayer循环播放拷贝的视频

 #! /bin/bash
# -------------------------------------------------------------------
# 该脚本结合树莓派pi用户自动挂载U盘功能,
# 实现自动拷贝U盘指定目录下文件至树莓派指定目录下,进行文件解压缩等操作
# 然后进行视频文件播放;
# 增加脚本自动更新功能
# 注:如果树莓派指定目录下存在待拷贝文件,则不进行cp操作
# -------------------------------------------------------------------
# mntpath为树莓派默认将U盘挂载路径
mntpath="/media/udisk"
# mnt为插入U盘存放待拷贝视频的默认文件夹名称,默认为U盘根目录
mnt="/"
# destination为将U盘中的视频文件需要拷贝到树莓派的哪个文件夹
destination="/home/pi/media"
# 文件拷贝过程中播放"视频拷贝中"视频的全路径名.
audioAsync="${destination}/audiocopying.mp4"
# 文件拷贝或者zip包解压缩异常,需要播放的错误提示信息视频
errormedia="${destination}/error.mp4"
# 线程休眠时间(秒)
sleepsec=
# U盘待拷贝视频文件zip命名规则
pattern=".*[lL]uck[tT]est_.*\.zip$"
# 校验文件是否是mp4扩展名
mp4pattern=".+\.mp4$"
# 校验文件是否是shell脚本扩展名
shpattern=".+\.sh$"
# 待升级脚本所在目录
scriptpath="/home/pi/"
# 脚本名称
scriptname="test_ad_autodisplay.sh"
# 升级成功标识文件
updatedfile="updated"
# 默认播放得视频名称
defaultDisplayAudioName="default.mp4"
# zip包解压缩密码
# zip -P test@ *_lucktest_*.zip .mp4
# sudo unzip -P "$password" -o -q "${destination}/${timedate}/${medianame}" -d "${destination}/${timedate}"
password="test@123
# -------------------------------------------------------------------
# 入参 $:需要播放文件的全路径名称
# 传入待播放文件全路径名,检测并播放该文件
# -------------------------------------------------------------------
function checkAndDisplay(){
echo "INFO:display file name is:$1"
# 播放之前,先判断omxplayer是否安装
if command -v omxplayer > /dev/null;then
# omxplayer已安装,检测是否有omxplayer进程,如果有,需要kill该进程,播放新拷贝的文件
echo "INFO:omxplayer command found.Begin to check if have omxplayer process."
# 检测是否已启动omxplayer,如果已启动,需要kill掉omxplayer相关pid
count=`ps -ef|grep omxplayer|grep -v "grep"|wc -l`;
if [ == $count ];then
echo "INFO:omxplayer not started.Begin to display ${1} by omxplayer."
else
echo "INFO:omxplayer have stared.Begin to get its pid."
# 获取omxplayer相关pids进行kill
pids=`ps -ef|grep omxplayer|grep -v "grep"|awk '{print $2}'`
echo "INFO:omxplayer pids are:$pids"
if [ -n "$pids" ];then
pidarr=($pids)
for pid in ${pidarr[@]}
do
echo "INFO:kill omxplayer process id:$pid!"
sudo kill - $pid
done
fi
fi
else
echo "ERROR:omxplayer command has not found!Need to install omxplayer first!!!"
return
fi
echo "INFO:excute cmd:sudo nohup sudo omxplayer --no-osd --loop -r -o hdmi "$" >/dev/null 2>&1 &"
# nohup运行omxplayer,--no-osd config do no display status info on the screen
sudo nohup omxplayer --no-osd --loop -r -o hdmi "$1" >/dev/null >& &
if [ $? -eq ];then
echo "INFO:excute cmd:sudo nohup sudo omxplayer --no-osd --loop -r -o hdmi "$" >/dev/null 2>&1 & success!";
return
else
echo "ERROR:excute cmd:sudo nohup sudo omxplayer --no-osd --loop -r -o hdmi "$" >/dev/null 2>&1 & failure!";
return
fi
} # -------------------------------------------------------------------
# 入参 $:需要删除哪个目录下的所有视频目录
# 入参 $:排除$1下的该目录,不删除
# 删除指定目录下的所有目录,如果有$,则排除该目录不删除
# -------------------------------------------------------------------
function deleteDir(){
if [ -n $ ];then
echo "INFO:Need to delete the folders under the $1"
echo "INFO:Need to exclusion folder name is : $2"
if [ -d "${1}" ];then
for delfile in ${}/*
do
echo "INFO:check file:${delfile} if need to delete!"
if [ -f "${delfile}" ];then
echo "INFO:${delfile} is a file, not delete!"
else
echo "INFO:${delfile} is a folder,begin to check it!"
# 如果$2不为空,则进行排除删除,否则都删除
if [ -n $2 ];then
# 获取待校验文件名
delfoldername=${delfile##*/}
echo "INFO:current folder name is : ${delfoldername},exclusion folder name is : $2"
if [ $delfoldername != $ ];then
sudo rm -fr "${delfile}"
# 删除成功,打印成功信息
if [ $? -eq ];then
echo "INFO:delete folder:${delfile} success!"
else
echo "ERROR:delete folder:${delfile} failure!"
fi
else
echo "INFO:current folder name is equals to exclusion folder name,not delete"
fi
else
echo "INFO:begin to delete folder:${delfile}"
sudo rm -fr "${delfile}"
# 删除成功,打印成功信息
if [ $? -eq ];then
echo "INFO:delete folder:${delfile} success!"
else
echo "ERROR:delete folder:${delfile} failure!"
fi
fi
fi
done
else
echo "ERROR:${1} is not a directory!"
fi
else
echo "ERROR:parameter 1($1) is null,do nothing!";
fi
} # -------------------------------------------------------------------
# 入参 $:待播放视频根目录,该目录下存放的是yyyy-mm-dd的文件夹,文件夹内为播放的视频文件
# 自动播放视频功能,包括开机自动播放和拷贝异常恢复播放等,都由该方法实现
# 实现逻辑:对$destination目录进行ls -t排序,取最新时间文件夹里的mp4文件进行播放
# -------------------------------------------------------------------
function autoDisplaying(){
if [ -n $ ];then
echo "INFO:auto displaying folder:$1"
if [ -d "${1}" ];then
# 如果当前目录为dirctory,则进行ll -t,获取最新时间戳folder,然后获取folder里面的视频进行播放
# 按时间排序list folder
# sudo ls -lt $|grep -e '^d'|awk '{print $9}'
folders=`sudo ls -lt ${}|grep -e '^d'|awk '{print $9}'`
echo "INFO:auto displaying folders are : $folders"
# 是否已播放成功
isdisplayed=
if [ -n "$folders" ];then
foldersArray=($folders)
for((i=;i<${#foldersArray[@]};i++))
do
foldername=${foldersArray[i]}
# 判断该foldername文件夹下是否有mp4文件,有则播放,break;否则继续循环
for file4play in "${1}"/"${foldername}"/*
do
file4playname=${file4play##*/}
# file4playname
echo "$file4playname"|grep -E "$mp4pattern" > /dev/null
# 如果符合mp4扩展名,说明是需要播放的视频,进行播放
if [ $? -eq ];then
echo "INFO:autoDisplaying file:${file4playname}"
checkAndDisplay "$file4play"
if [ $? -eq ];then
isdisplayed=
# 跳出两层循环
break
fi
fi
done
done
else
echo "ERROR:auto displaying folder:$1 has no child folder!"
fi
# 如果未播放成功,则需要播放默认视频
if [ ! -n "$isdisplayed" ];then
echo "WARN:$1 have no audio to display,begin to display default audio!"
# 如果待播放目录下没有视频目录,则判断该目录($)下是否有默认播放视频($defaultDisplayAudioName),如果有则播放
# 目前 $ == $destination
if [ -f "${1}/${defaultDisplayAudioName}" ];then
checkAndDisplay "${1}/${defaultDisplayAudioName}"
elif [ -f "${destination}/${defaultDisplayAudioName}" ];then
# 如果$1目录下没有,则判断${destination}目录下是否有默认播放视频
checkAndDisplay "${destination}/${defaultDisplayAudioName}"
else
echo "ERROR:default display file:${1}/${defaultDisplayAudioName} not exist,auto display do nothing!"
fi
fi
else
echo "ERROR:auto displaying file path:${1} is not a directory!"
fi
else
echo "ERROR:parameter 1($1) is null,auto display do nothing!"
fi
} # -------------------------------------------------------------------
#
# 入参 $:升级的脚本文件全路径
# 入参 $:$1脚本名称
#
# 处理逻辑如下:
# 重命名(加上当前时间戳)$scriptpath/$scriptname进行备份,
# 将$1脚本拷贝到$scriptpath目录下,
# 将$1文件重命名为$scriptname,reboot系统
#
# -------------------------------------------------------------------
function updateShellScript(){
# 如果脚本存在,则执行备份和拷贝操作
if [ -f "$scriptpath/$scriptname" ];then
timestp=`date "+%Y%m%d%H%M%S"`
# 备份当前被替换的脚本
sudo mv "${scriptpath}/${scriptname}" "${scriptpath}/${scriptname}.${timestp}"
if [ $? -eq ];then
echo "INFO:excute cmd:sudo mv ${scriptpath}/${scriptname} $scriptpath/${scriptname}.${timestp} success!"
# 拷贝$1至$scriptpath目录下
sudo cp -f "$1" "$scriptpath"
if [ $? -eq ];then
# 如果$ == $scriptname,则不需要执行mv操作
if [ "$2"!="$scriptname" ];then
# 如果拷贝成功,则执行mv操作
sudo mv "${scriptpath}/$2" "${scriptpath}/${scriptname}"
# 如果mv操作成功,则执行reboot命令
if [ $? -eq ];then
echo "INFO:excute cmd:sudo mv ${scriptpath}/$2 ${scriptpath}/${scriptname} success!"
# 重命名成功,给该脚本添加执行权限
sudo chmod +x "${scriptpath}/${scriptname}"
# 启动之前创建升级成功标识文件,防止循环启动!
if [ ! -f "${scriptpath}/${updatedfile}" ];then
sudo touch "${scriptpath}/${updatedfile}"
fi
echo "INFO:shell script update finished.Reboot!!!"
# 增加suid权限
sudo chmod u+s /sbin/reboot
reboot
else
echo "INFO:excute cmd:sudo mv ${scriptpath}/$2 ${scriptpath}/${scriptname} failure!Rollback!"
echo "INFO:excute cmd:sudo mv ${scriptpath}/${scriptname}.${timestp} ${scriptpath}/${scriptname}!"
#如果mv操作不成功,则执行回滚操作
sudo mv "${scriptpath}/${scriptname}'.'${timestp}" "${scriptpath}/${scriptname}"
if [ $? -eq ];then
echo "INFO:excute cmd:sudo mv ${scriptpath}/${scriptname}.${timestp} ${scriptpath}/${scriptname} success!"
else
echo "INFO:excute cmd:sudo mv ${scriptpath}/${scriptname}.${timestp} ${scriptpath}/${scriptname} failure!"
fi
fi
else
# 复制成功,给该脚本添加执行权限
sudo chmod +x "${scriptpath}/${scriptname}"
# 启动之前创建标识升级标识文件,防止循环启动!
if [ ! -f "${scriptpath}/${updatedfile}" ];then
sudo touch "${scriptpath}/${updatedfile}"
fi
echo "INFO:shell script update finished.Reboot!!!"
# 增加suid权限
sudo chmod u+s /sbin/reboot
reboot
fi
else
# 如果拷贝不成功,则将原备份脚本进行回滚
sudo mv "${scriptpath}/${scriptname}'.'${timestp}" "${scriptpath}/${scriptname}"
if [ $? -eq ];then
echo "INFO:excute cmd:sudo mv ${scriptpath}/${scriptname}.${timestp} ${scriptpath}/${scriptname} success!"
else
echo "INFO:excute cmd:sudo mv ${scriptpath}/${scriptname}.${timestp} ${scriptpath}/${scriptname} failure!"
fi
fi
else
echo "ERROR:excute cmd:sudo mv $scriptpath/$scriptname $scriptpath/${scriptname}.${timestp} failure!Stop update shell script!!!"
fi
else
# 如果脚本不存在,则执行拷贝和重命名操作
echo "ERROR:shell script file:$scriptpath/$scriptname not exist.Copy $1 to path:$scriptpath"
sudo cp "$1" "$scriptpath"
if [ $? -eq ];then
echo "INFO:Copy $1 to path:$scriptpath success!"
echo "INFO:rename file:$2 to $scriptname"
sudo mv "$scriptpath/$2" "$scriptpath/$scriptname"
if [ $? -eq ];then
echo "INFO:excute cmd:sudo mv $scriptpath/$2 $scriptpath/$scriptname success!"
# 重命名成功,给该脚本添加执行权限
sudo chmod +x "${scriptpath}/${scriptname}"
# 启动之前创建标识升级标识文件,防止循环启动!
if [ ! -f "${scriptpath}/${updatedfile}" ];then
sudo touch "${scriptpath}/${updatedfile}"
fi
# 增加suid权限
sudo chmod u+s /sbin/reboot
reboot
else
echo "ERROR:excute cmd:sudo mv $scriptpath/$2 $scriptpath/$scriptname failure!"
fi
else
echo "ERROR:Copy $1 to path:$scriptpath failure!"
fi
fi
} # -------------------------------------------------------------------
#
# 入参 $:U盘挂载目录
#
# 检测待拷贝U盘指定目录下是否存在指定格式zip包,
# 如果存在,则拷贝至PI的指定目录下并解压,解压和拷贝过程中,播放"视频同步中"的视频
# 拷贝结束后,播放新拷贝的视频,删除早前的视频目录
#
# 、检测到U盘插入信息,搜索“*测试_*.zip”文件,将该文件拷贝到树莓派文件系统并解压;停止原有视频播放,改为显示“视频同步中”图片;
# 、计算每个mp4文件的Hash并和“目录名_hash”文件中的Hash值进行比较,全部相同则成功,有任一文件Hash值校验失败则显示失败;(TODO)
# 、成功则将播放目录连接到当前copy进来的目录,并删除早期的视频目录,重新开始播放
# 、失败则播放特定的图片(5s),提示错误,之后删除刚拷贝的文件和目录,重新播放之前的目录
# 、树莓派记录视频更新日志,播放日志(具体格式待定,作为二期扩展功能)。(TODO)
#
# -------------------------------------------------------------------
function checkAndCopyZipFileToPi(){
if [ -d "${1}/${mnt}" ];then
echo "INFO:${1}/${mnt} is existed."
# 循环该目录文件,判断是否需要进行文件拷贝
for media in ${}/$mnt/*
do
# 如果待拷贝文件为file,则判断文件名称是否符合zip命名规则,如果符合,则执行拷贝
if [ -f "$media" ];then
echo "INFO:begin to check if file $media matchs to $pattern!"
# 获取待校验文件名
medianame=${media##*/}
echo "INFO:file name is $medianame"
# 校验medianame是否符合$pattern
echo "$medianame"|grep -E "$pattern" > /dev/null
if [ $? -eq ];then
timedate=`date "+%Y-%m-%d"`
echo "INFO:$medianame matchs $pattern,copy it to ${destination}/${timedate}!"
# 如果找到符合命名规范的文件,则播放“视频同步中”的视频
checkAndDisplay "$audioAsync"
if [ ! -d "${destination}/${timedate}" ];then
sudo mkdir -p "${destination}/${timedate}"
if [ $? -eq ];then
echo "INFO:excute cmd:mkdir -p ${destination}/${timedate} success!"
else
echo "INFO:excute cmd:mkdir -p ${destination}/${timedate} failure!"
#如果目录创建失败,需要播放之前最新目录下的视频
autoDisplaying "${destination}"
fi
fi
# 安全起见,拷贝之前,再校验一遍目标目录是否存在
if [ -d "${destination}/${timedate}" ];then
# -f:if an existing destination file cannot be opened, remove it and try again
sudo cp -f "$media" "${destination}/${timedate}"
# 如果zip文件拷贝到PI指定目录成功,则执行解压缩和播放等逻辑
# 、成功则将播放目录连接到当前copy进来的目录,并删除早期的视频目录,重新开始播放
if [ $? -eq ];then
echo "INFO:excute cmd:cp -n $media ${destination}/${timedate} success!"
# unzip copy进来的zip包,-o:overwrite files WITHOUT prompting,-q:quiet mode
sudo unzip -P "$password" -o -q "${destination}/${timedate}/${medianame}" -d "${destination}/${timedate}"
# 如果unzip成功,则播放拷贝的文件,删除早前的视频目录
if [ $? -eq ];then
echo "INFO:excute cmd:sudo unzip -P $password -o -q ${destination}/${timedate}/${medianame} ${destination}/${timedate} success!"
ifhasmp4=
for unzipfile in "${destination}"/"${timedate}"/*
do
filename=${unzipfile##*/}
# 校验filename是否是shell脚本扩展名,如果是,则说明是需要升级的脚本
echo "$filename"|grep -E "$shpattern" > /dev/null
if [ $? -eq ];then
# 如果脚本升级成功标识文件存在,则说明已升级成功,不再进行升级;将该标识文件进行删除,以便执行下次升级
if [ -f "${scriptpath}/${updatedfile}" ];then
echo "INFO:${scriptpath}/${updatedfile} file existed!Stop update!"
sudo rm -f "${scriptpath}/${updatedfile}"
if [ $? -eq ];then
echo "INFO:excute cmd:sudo rm -f ${scriptpath}/${updatedfile} success!"
else
echo "INFO:excute cmd:sudo rm -f ${scriptpath}/${updatedfile} failure!"
fi
else
updateShellScript "$unzipfile" "$filename"
fi
fi
# 校验filename是否是mp4扩展名
echo "$filename"|grep -E "$mp4pattern" > /dev/null
# 如果符合mp4扩展名,说明是需要播放的视频,进行播放
if [ $? -eq ];then
ifhasmp4=
#线程休眠几秒,再执行播放
sleep $sleepsec
checkAndDisplay "$unzipfile"
# 如果checkAndDisplay播放成功,则删除早期的视频目录
if [ $? -eq ];then
deleteDir "${destination}" "${timedate}"
else
# 先播放error视频提示播放失败信息
checkAndDisplay "${errormedia}"
sleep $sleepsec
# 如果checkAndDisplay播放不成功,则播放早期的视频
autoDisplaying "${destination}"
fi
fi
done
# 如果zip包解压后未发现mp4文件,则播放早期视频
if [ ! -n "$ifhasmp4" ];then
echo "ERROR:${destination}/${timedate}/${medianame} not have mp4 file,display before audio!"
autoDisplaying "${destination}"
fi
else
echo "INFO:excute cmd:sudo unzip -P $password -o -q ${destination}/${timedate}/${medianame} ${destination}/${timedate} failure!"
# 先播放error视频提示播放失败信息
checkAndDisplay "${errormedia}"
sleep $sleepsec
# 解压缩失败,播放之前最新目录下的视频
autoDisplaying "${destination}"
fi
else
# 、拷贝失败则播放特定的图片(5s),提示错误,之后删除刚拷贝的文件和目录,重新播放之前的目录
# (不能删除刚拷贝的文件和目录)否则存在以下问题:
# 存在第一次拷贝成功,然后删除了早期的视频目录,第二次进行覆盖拷贝时异常,如果删除刚拷贝的文件和目录,则会导致无视频播放的问题
echo "ERROR:excute cmd:cp -n $media ${destination}/${timedate} failure!"
# 播放拷贝失败视频
checkAndDisplay "${errormedia}"
sleep $sleepsec
# 播放之前最新目录下的视频
autoDisplaying "${destination}"
fi
else
echo "INFO:${destination}/${timedate} file path is not exist!"
#如果目录不存在,需要播放之前最新目录下的视频
autoDisplaying "${destination}"
fi
else
echo "WARN:$medianame not matchs $pattern,not copy it!"
fi
fi
done
fi
} # -------------------------------------------------------------------
# 循环检测是否有USB设备插入树莓派,手动挂载该USB设备至/media/udisk/${i}目录下
# 手动挂载USB设备时,需要判断该设备是否已挂载,如果已挂载,则不再进行挂载
# 当检测到无USB设备插入时,需要将挂载的信息手动umount,删除挂载的目录等
# -------------------------------------------------------------------
function autoScanUsbDeviceAndMount(){
while true
do
timeb=`date "+%Y-%m-%d %H:%M:%S"`
echo "${timeb}:=======================Scan USB devices start=============================="
if [ ! -d $mntpath ];then
echo "WARN:$mntpath file path not exist,excute mkdir cmd create it!"
sudo mkdir -p $mntpath
fi
#获取挂载的usb devices,挂载之前需要判断该USB设备是否已挂载,如果已挂载,则不再执行挂载操作
fdisks=`sudo fdisk -l|grep -E "^/dev/sd[a-z]1"|grep -v "Disk"|awk '{print $1}'`
echo "INFO:usb devices are : $fdisks"
if [ -n "$fdisks" ];then
fdiskArray=($fdisks)
for((i=;i<${#fdiskArray[@]};i++))
do
filesystem=${fdiskArray[i]}
#检测该USB设备是否已挂载
count=`df -h|grep -E "^${filesystem}"|grep -v "Filesystem"|wc -l`;
echo "INFO:excute cmd:df -h|grep -E '^${filesystem}'|grep -v 'Filesystem'|wc -l,count:${count}"
if [ $count -gt ];then
echo "WARN:${filesystem} have already mounted!"
else
if [ ! -d "${mntpath}/${i}" ];then
echo "WARN:${mntpath}/${i} file path not exist,excute mkdir cmd create it!"
sudo mkdir -p "${mntpath}/${i}"
fi
echo "INFO:excute mount cmd to mount ${filesystem} on ${mntpath}/${i}"
sudo mount -o uid=${USER},gid=${USER} ${filesystem} ${mntpath}/${i}
# 挂载成功,判断路径是否存在,存在则执行拷贝
if [ $? -eq ];then
echo "INFO:excute cmd:sudo mount -o uid=${USER},gid=${USER} ${filesystem} ${mntpath}/${i} success!"
checkAndCopyZipFileToPi "${mntpath}/${i}"
else
echo "ERROR:excute cmd:sudo mount -o uid=${USER},gid=${USER} ${filesystem} ${mntpath}/${i} failure!"
fi
fi
done
else
# 没有USB设备,如果脚本升级成功标识文件存在,将其删除,
# 以便USB设备插入后,如果升级包中包含脚本升级文件做升级处理
if [ -f "${scriptpath}/${updatedfile}" ];then
echo "INFO:${scriptpath}/${updatedfile} file existed!Remove it!"
sudo rm -f "${scriptpath}/${updatedfile}"
if [ $? -eq ];then
echo "INFO:excute cmd:sudo rm -f ${scriptpath}/${updatedfile} success!"
else
echo "INFO:excute cmd:sudo rm -f ${scriptpath}/${updatedfile} failure!"
fi
fi
# 如果没有USB设备,则需要将mount的设备进行umount,删除该USB设备mount目录下对应的文件夹
usbmounts=`df -h |grep -E "^/dev/sd[a-z]1"|grep -v "Filesystem"|awk '{print $1" "$6}'`
if [ -n "$usbmounts" ];then
usbmountArray=($usbmounts)
for((j=;j<${#usbmountArray[@]};j=j+))
do
umdevice=${usbmountArray[j]}
umountpath=${usbmountArray[j+]}
echo "INFO:prepare to umount device:${umdevice} from file path:${umountpath}"
sudo umount "${umountpath}"
echo "INFO:${umdevice} umount from ${umountpath} success!"
echo "INFO:prepare to remove path:${umountpath}"
# 判断挂载的目录是否存在,存在则删除
if [ -d "${umountpath}" ];then
sudo rm -fr "${umountpath}"
echo "INFO:rm -fr ${umountpath} success!"
else
echo "INFO:path ${umountpath} not exist!"
fi
done
fi
fi
timee=`date "+%Y-%m-%d %H:%M:%S"`
echo "${timee}:=======================Scan USB devices end================================"
echo "INFO:Thread sleep ${sleepsec}s!"
sleep $sleepsec
echo "INFO:Thread wakeup!"
done
} # -------------------------------------------------------------------
# @Deprecated
# INFO:该函数暂时废弃
# 循环检查是否有U盘挂载至树莓派
# -------------------------------------------------------------------
function autoScanUsbDeviceMounted(){
while true
do
timeb=`date "+%Y-%m-%d %H:%M:%S"`
echo "${timeb}:=======================Scan start=============================="
if [ ! -d $mntpath ];then
echo "WARN:$mntpath file path not exist,excute mkdir cmd create it!"
sudo mkdir -p $mntpath
else
echo "INFO:$mntpath file path is existed."
# 循环U盘挂载目录,判断是否有U盘挂载至当前树莓派
for file in $mntpath/*
do
# 如果当前file为文件目录
if [ -d $file ];then
echo "INFO:$file is directory"
# 如果当前目录下存在$mnt文件夹,说明是U盘挂载待拷贝文件目录
if [ -d "$file/$mnt" ];then
echo "INFO:$file/$mnt is existed."
# 循环该目录文件,判断是否需要进行文件拷贝
for media in $file/$mnt/*
do
# 如果待拷贝文件为file,则判断目的文件目录是否存在同名文件,存在同名文件不进行拷贝
if [ -f "$media" ];then
echo "INFO:begin to copy $media to $destination"
# 获取待拷贝文件名
medianame=${media##*/}
echo "INFO:media name is $medianame"
# 如果目的文件夹下不存在同名文件,则执行拷贝
if [ ! -f "$destination/$medianame" ];then
cp -n "$media" $destination
echo "INFO:copy file:$medianame to $destination success!Begin to display by omxplayer!"
# omxplayer需要循环播放的文件
displayfilename="$destination/$medianame"
# 播放之前,先判断omxplayer是否安装
if command -v omxplayer > /dev/null;then
# omxplayer已安装,检测是否有omxplayer进程,如果有,需要kill该进程,播放新拷贝的文件
echo "INFO:omxplayer command found.Begin to check if have omxplayer process."
checkAndDisplay "$displayfilename"
else
echo "ERROR:omxplayer command has not found!!!"
fi
else
echo "WARN:$destination existed media file:$medianame,not excute copy cmd!"
fi
fi
done
fi
else
echo "WARN:$file is file"
fi
done
fi
timee=`date "+%Y-%m-%d %H:%M:%S"`
echo "${timee}:=======================Scan end================================"
echo "INFO:Thread sleep ${sleepsec}s!"
sleep $sleepsec
echo "INFO:Thread wakeup!"
done
} # -------------------------------------------------------------------
# 树莓派启动后,执行该方法初始化开机自动播放视频\扫描USB是否插入然后自动挂载复制相关视频文件等操作
# -------------------------------------------------------------------
function bootStrapInit(){
# 初始化默认播放最新目录下文件夹中的最新视频
echo "INFO:bootstrap init excute method:autoDisplaying(${destination})!"
autoDisplaying "${destination}"
echo "INFO: bootstrap init excute method:autoScanUsbDeviceAndMount()"
autoScanUsbDeviceAndMount } bootStrapInit

4.后台启动脚本

 nohup ./test_ad_autodisplay.sh >>scan.log >& & 

5.开机自动启动脚本

linux添加开机自启动脚本示例详解

/etc/rc.local添加如下脚本:

sudo /home/pi/test_ad_autodisplay.sh >> /home/pi/`date "+%Y-%m-%d"`.log

树莓派USB存储设备自动挂载并通过脚本实现自动拷贝,自动播放视频,脚本自动升级等功能的更多相关文章

  1. 树莓派-USB存储设备自动挂载

    简单介绍实现命令行下USB存储设备自动挂载的方法,Linux gnome/kde窗口环境下有移动存储的管理程序,可以实现自动挂载移动存储设备,但是在命令行下 通常需要用mount命令手动挂载USB存储 ...

  2. 如何查找Mac上的USB存储设备使用痕迹

    最近刚好有个案子的证物主机是MBP, OS X版本为El Capitan,案况与营业秘密外泄有关,当中要找有关USB存储设备的使用痕迹. 要提醒大家的是,不同版本的OS X,各种迹证的存放文件名称及路 ...

  3. 禁用USB存储设备(不重启)

    Title:禁用USB存储设备(不重启) -- 2012-09-13 12:08 在win2003实验,USB存储禁止,无需重启! stop usbrw.reg ------------------- ...

  4. 工业控制系统USB存储设备可信管理方案的(ICICS2015)论文PPT:TMSUI: A Trust Management Scheme

    本PPT是发表在ICICS2015 大会的论文 TMSUI: A Trust Management Scheme of USB Storage Devices for Industrial Contr ...

  5. 将windows系统装到USB存储设备

    需求: 1)一般公司比较规范,计算机系统有严格的限制策略,如果自己不懂得如何更改或者没有权限更改,将极其不便. 2)计划在家里完成在公司未完成的事,甚至异地出差觉得携带笔记本不太方便,寻找更便携的设备 ...

  6. linux下如何使用USB存储设备

    如何在Linux环境中使用USB接口的 存储 设备?这是各大电脑论坛上出现得比较多的一个问题,同此可见这也是摆在许多电脑玩家面前的一道难题. 本文就为您提供一套完美的解决方案,通过下面的方法,您仅可以 ...

  7. 测试 USB 存储设备读写性能(Mb/s),平均读写速度等

    1.将U盘(USB3.0)插入被测试机器,假定识别设备为sdc2.创建vfat文件系统分区/dev/sdb1分区容量大于30GBumount /dev/sdc1mkfs -t vfat /dev/sd ...

  8. 查找连接过的USB存储设备

    gp "HKLM:\SYSTEM\CurrentControlSet\Enum\USBSTOR\*\*"|select friendlyname,CompatibleIDs,mfg ...

  9. Linux系统中存储设备的两种表示方法

    转:https://blog.csdn.net/holybin/article/details/38637381 一.对于IDE接口的硬盘的两种表示方法: 1.IDE接口硬盘,对于整块硬盘的两种表示方 ...

随机推荐

  1. JVM-GC算法(三)-分代收集算法

    对象分类 上次已经说过,分代收集算法是针对对象的不同特性,而使用合适的算法,这里面并没有实际上的新算法产生.与其说分代收集算法是第四个算法,不如说它是对前三个算法的实际应用.  首先我们来探讨一下对象 ...

  2. java基础阶段几个必会面试题

    摘自:https://www.cnblogs.com/zn19961006/p/11869182.html java基础阶段几个必会面试题 目录 1.说出你对面向对象的理解 在我理解,面向对象是向现实 ...

  3. cropper.js

    https://github.com/fengyuanchen/cropper/blob/master/README.md Options See the available options of C ...

  4. android data binding jetpack IV 绑定一个方法另一种写法和参数传递

    android data binding jetpack VIII BindingConversion android data binding jetpack VII @BindingAdapter ...

  5. http1.1管线话 vs htttp2.0 多路复用

    图中第一种请求方式,就是单次发送request请求,收到response后再进行下一次请求,显示是很低效的. 于是http1.1提出了管线化(pipelining)技术,就是如图中第二中请求方式,一次 ...

  6. GLSL语法入门

    变量 GLSL的变量命名方式与C语言类似.变量的名称可以使用字母,数字以及下划线,但变量名不能以数字开头,还有变量名不能以gl_作为前缀,这个是GLSL保留的前缀,用于GLSL的内部变量.当然还有一些 ...

  7. LC 833. Find And Replace in String

    To some string S, we will perform some replacement operations that replace groups of letters with ne ...

  8. .net core 入门一

    官网教程:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-3.0&tabs=wind ...

  9. ubuntu中配置jdk1.8

    方法/步骤   1 首先,百度搜索jdk,选择第一个,网站是Oracle Jdk.点击进去 步骤阅读 2 点击Download,到官网下载linux版本的jdk.选择自己对应的操作系统及32或64位版 ...

  10. Python:Base4(map,reduce,filter,自定义排序函数(sorted),返回函数,闭包,匿名函数(lambda) )

    1.python把函数作为参数: 在2.1小节中,我们讲了高阶函数的概念,并编写了一个简单的高阶函数: def add(x, y, f): return f(x) + f(y) 如果传入abs作为参数 ...