Reputation: 41
I have an IP camera that sends a photo every minute to a folder on a PC (Linux) with (mv *20150501* 20150501)
.
Where the camera sends the following filename:
Schedule_20150501-103642.jpg
I would like to make a shell script that:
mencoder "mf://*.jpg" -mf fps=12:type=jpg -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell:vbitrate=7000 -oac copy -o Zeitraffer`**20150501**.mp4
Base folder is: snap
Sub folder: snap/(date +%YYYY%mm%dd)
Until now, I do all that manually and separately using mv
. Then I move into the folders and modify the script for the time lapse. :-(
Until now, I have a script to make at least a bulk of folders by date:
#!/bin/bash
read -p "Geben Sie den ersten Ordner an (JJJJMMTT): " now
read -p "Geben Sie den letzten Ordner an (JJJJMMTT): " end
while [ "$now" != "$end" ] ;
do
now=`date +"%Y%m%d" -d "$now +1 day"`;
mkdir $now
done
Any idea?
Upvotes: 3
Views: 2942
Reputation: 34353
Here's a solution I use to sort images and videos by their creation date, based on ExifTool:
#!/bin/bash
# Based on Exif metadata, gets the date and time a file was created
get_date_and_time() {
local result;
result=$(exiftool -binary -DateTimeOriginal "$1")
# If the file metadata doesn't contain DateTimeOriginal try with another tag
if [ -z "$result" ]; then
result=$(exiftool -binary -CreateDate "$1")
fi
# https://www.shellcheck.net/wiki/SC2059
printf "%s" "$result"
}
main() {
# When the script's called without arguments, sort
# files found in the current directory
if (( $# != 1 )); then
dir_with_files="."
# Otherwise, use the first argument as the directory
else
dir_with_files="$1"
fi
echo "moving files in \"$dir_with_files\""
for f in "$dir_with_files"/*
do
if [ -f "$f" ]; then
date_time=$(get_date_and_time "$f")
if [ -n "$date_time" ]; then
# Remove the time and keep the date by removing
# everything after the first space
date="${date_time%% *}"
# Replace all colons with dashes in the date
dir_name="${date//:/-}"
# Create the directory if it doesn't exist yet
if [ ! -d "$dir_with_files/$dir_name" ]; then
mkdir --verbose "$dir_with_files/$dir_name"
fi
mv --no-clobber --verbose "$f" "$dir_with_files/$dir_name"
else
echo "No date for $f"
fi
fi
done
}
main "$@"
If you put that code in sort_by_day.sh
and make it executable with chmod +x sort_by_day.sh
, you can call it like this:
./sort_by_day.sh
to sort files in the current directory../sort_by_day.sh my_images
to sort files in the directory my_images
.Based on the Exif tags DateTimeOriginal
or —if the file doesn't have that tag— CreateDate
, the script will create directories like 2023-05-23
and move files that were created on that day into the corresponding directory.
If a file doesn't have those Exif tags, the script does not move it.
I have used this to sort JPGs and MOVs.
Upvotes: 1
Reputation: 41
First of all, Thanks to every comment of you!!! REGEX is toooo difficult for me. Thanks alyway. After a lot of research today I fit together a lot of puzzle parts. What I got is this: The only thing is that if there is already a folder the respective files are not copied due to the while function. But as the script stops one day before today this should not be a problem. Then I made two more scripts for the case in the past I forgot to make a movie it will be created. The other checks if the MP4 file already exists in the plex folder and if not copy the file there. Actually I just modified the script for that.
The script for "normal" work:
#!/bin/bash
read -p "Geben Sie den ersten Ordner an (JJJJMMTT): " begin
end=$(date +%Y%m%d -d "-1 day")
while [ $begin != $end ]
do
begin=`date +"%Y%m%d" -d "$begin +1 day"`
if [ ! -d $begin ] # Prüfen, ob es den Ordner gibt.
then
/bin/mkdir $begin
echo "Ordner $begin erstellt"
mv *$begin*.jpg $begin
echo "Bilder vom $begin verschoben nach $begin"
cd $begin
$(mencoder mf://*.jpg -mf fps=12:type=jpg -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell:vbitrate=7000 -oac copy -o Zeitraffer$begin.mp4)
cp Zeitraffer$begin.mp4 /Plexfolder/
echo "Kopiere Zeitraffer$begin.mp4 nach /RAID5/filme/Kamera/"
cd ..
fi
done
The script to check if the MP4 file exists if not creates it and copies to the plex folder:
#!/bin/bash
read -p "Geben Sie den ersten Ordner an (JJJJMMTT): " begin
end=$(date +%Y%m%d -d "-1 day")
while [ $begin != $end ]
do
begin=`date +"%Y%m%d" -d "$begin +1 day"`
if [ -d $begin ]
then
cd $begin
if [ ! -f Zeitraffer$begin.mp4 ] #Prüfen, ob es eine MP4 Datei gibt
then
$(mencoder mf://*.jpg -mf fps=12:type=jpg -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell:vbitrate=7000 -oac copy -o Zeitraffer$begin.mp4)
cp Zeitraffer$begin.mp4 /plexfolder/
echo "Kopiere Zeitraffer$begin.mp4 nach /plexfolder/"
fi
cd ..
fi
done
And the one to copy the missing MP4 file to the plex folder:
#!/bin/bash
read -p "Geben Sie den ersten Ordner an (JJJJMMTT): " begin
end=$(date +%Y%m%d -d "-1 day")
while [ $begin != $end ]
do
begin=`date +"%Y%m%d" -d "$begin +1 day"`
if [ -d $begin ]
then
cd $begin
if [ ! -f "/plexfolder/Zeitraffer$begin.mp4" ]
then
cp Zeitraffer$begin.mp4 /RAID5/filme/Kamera/
echo "Kopiere Zeitraffer$begin.mp4 nach /RAID5/filme/Kamera/"
fi
cd ..
fi
done
And you know what's the best??? IT REALLY WORKS!!! I cannot believe that I did it!!!
Thanks a lot for your help!!!
Upvotes: 1
Reputation: 899
This solution will autoselect the first date and move all images together and process them afterwards with mencoder. The solution has several assumtions that should be easy to achieve:
Based on these assumptions, the solution is pretty efficient, since it moves all pictures of a single day at the same time. I included 2 methods to search for the earliest day to start. If you produce a LOT of files each day, it might be faster to look at the directories. If you have directories for many years (so, tens of thousands of directories), it might be faster to look at the remaining images instead.
today=$(date +"%Y%m%d" -d "now")
#first day to process based on existing images
day=$(ls Schedule_* | grep -o "[[:digit:]]\{8\}" | uniq | sort | tail -n1)
# first day to process based on existing folders (might be faster)
#day=$(find . -type d -regex "./[0-9]+" -printf '%P\n' | sort | tail -n1)
# initial increment of day
day=$(date +"%Y%m%d" -d "$day +1 day")
while [ $day -lt $today ] ; do
mkdir $day
mv Schedule_${day}-*.jpg ${day}/. 2>/dev/null
cd $day
# run mencoder
cd ..
day=$(date +"%Y%m%d" -d "$day +1 day")
done
Upvotes: 0
Reputation: 231
Here is a sample that can help you:
shopt -s nullglob
for f in Schedule*.jpg
do
dir_date=`echo "$f"|sed -e 's/Schedule_\([0-9]\{8\}\)-.*/\1/'`
mkdir -p "$dir_date"
mv "$f" "$dir_date"
done
for d in 20*
do
if [[ -d "$d" ]]
then
cd "$d"
if [[ ! -f Zeitraffer"$d".mp4 ]]
then
# Run mencoder here
fi
cd ..
fi
done
Nullglob is used, so if no files match, for
will not take Schedule*.jpg
pattern literally. Then extract date part with sed
. Adding -p
to mkdir
makes sure that it doesn't print error if the directory already exists, so there is no need to check for it separately.
Upvotes: 0