-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathsnaprecovery.sh
executable file
·147 lines (116 loc) · 4.83 KB
/
snaprecovery.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/bin/sh
#
# by Siddharth Dushantha
#
# Colored log indicators
GOOD="\033[92;1m[✔]\033[0m"
BAD="\033[91;1m[✘]\033[0m"
INFO="\033[94;1m[I]\033[0m"
RUNNING="\033[37;1m[~]\033[0m"
NOTICE="\033[93;1m[!]\033[0m"
usage(){
cat <<EOF
usage: snaprecovery [-n, --no-merge] [SERIAL]
The serial number of the device can be found by running 'adb devices'.
It is not necessary if only one device is connected in adb devices.
Options:
-n, --no-merge don't merge videos with their respective overlays
EOF
exit 1
}
# Determines whether or not to merge videos with overlays. Must be unset or null/empty to disable.
MERGE=yes
while [ "$1" ] ; do
case $1 in
-h|--help) usage ;;
-n|--no-merge) unset MERGE ;;
*) SERIAL="$1" ;;
esac
shift
done
for DEPENDENCY in adb awk ${MERGE:+ffmpeg stat touch}; do
if ! command -v "$DEPENDENCY" >/dev/null 2>&1; then
printf "%b Could not find '%s', is it installed?\n" "$BAD" "$DEPENDENCY"
exit 1
fi
done
# Number of devices connected to computer through USB
DEVICESCOUNT="$(adb devices | awk 'NF && NR>1' | wc -l)"
# If only one device is connected, use its serial, otherwise the user is required to specify a serial.
if [ "$DEVICESCOUNT" -eq 1 ]; then
SERIAL="$(adb devices | awk 'NF && FNR==2{print $1}')"
else
[ $# -eq 0 ] || [ "$1" = "" ] && usage
fi
SNAPS_DIRECTORY="snaps_$SERIAL"
# Check if the device is authorized
DEVICESTATUS="$(adb devices | grep "$SERIAL" | cut -f2)"
if [ "$DEVICESTATUS" = 'unauthorized' ]; then
printf "%b Device '%s' is not authorized.\n" "$BAD" "$SERIAL"
printf "%b Check for a confirmation dialog on your device.\n" "$NOTICE"
exit 1
fi
# Get the product model (e.g. SM-AF10F). If a product model is not found, then
# that means the given serial is invalid.
if ! PRODUCT_MODEL=$(adb -s "$SERIAL" shell getprop ro.product.model 2> /dev/null);then
printf "%b Looks like '%s' is an invalid device\n" "$BAD" "$SERIAL"
exit 1
fi
printf "%b Target device: %s (%s)\n" "$INFO" "$SERIAL" "$PRODUCT_MODEL"
# Restart adb as root. Root access is needed in order to access the files
adb -s "$SERIAL" root > /dev/null 2>&1
if ! adb -s "$SERIAL" pull -a /data/user/0/com.snapchat.android/files/file_manager/chat_snap/ .snaprecovery-tmp > /dev/null 2>&1; then
printf "%b %b\n" "$BAD" "This device is not rooted!"
exit 1
fi
mkdir -p "$SNAPS_DIRECTORY"
TOTAL_FILES=$(find .snaprecovery-tmp -mindepth 1 | wc -l)
COUNT=1
# If MERGE is unset, rename all files without merging
if [ -z "${MERGE:+x}" ]; then
for SNAP in .snaprecovery-tmp/*.chat_snap.[012]; do
EXTENSION=$(file --mime-type -b "$SNAP" | sed 's/.*\///g')
NEW_FILENAME="${SNAP%chat_snap.[012]}$EXTENSION"
# \r Move cursor to the start of the current line
# \e[2K Clear whole line
printf "\r\033[2K%b Recovering [%d/%d]: %s" "$RUNNING" "$COUNT" "$TOTAL_FILES" "$NEW_FILENAME"
mv "$SNAP" "$NEW_FILENAME"
COUNT=$((COUNT + 1))
done
rm -f .snaprecovery-tmp/*.json
else
# If MERGE is set, rename singletons and merge overlays
# For files without overlays, rename with the correct extension
for SNAP in .snaprecovery-tmp/*.chat_snap.0; do
EXTENSION=$(file --mime-type -b "$SNAP" | sed 's/.*\///g')
NEW_FILENAME="${SNAP%chat_snap.0}$EXTENSION"
# \r Move cursor to the start of the current line
# \e[2K Clear whole line
printf "\r\033[2K%b Recovering [%d/%d]: %s" "$RUNNING" "$COUNT" "$TOTAL_FILES" "$NEW_FILENAME"
mv "$SNAP" "$NEW_FILENAME"
COUNT=$((COUNT + 1))
done
# For files with overlays, use ffmpeg to merge the overlay
for SNAP in .snaprecovery-tmp/*.chat_snap.1; do
BASE="$SNAP"
OVERLAY="${SNAP%1}2"
NEW_FILENAME="${SNAP%.chat_snap.1}.merged.mkv"
# if <name>.chat_snap.2 doesn't exist, don't attempt to merge anything
[ -f "$OVERLAY" ] || continue
# \r Move cursor to the start of the current line
# \e[2K Clear whole line
printf "\r\033[2K%b Recovering [%d/%d]: %s" "$RUNNING" "$COUNT" "$TOTAL_FILES" "$NEW_FILENAME"
# merge overlay onto video
ffmpeg -loglevel quiet -i "$BASE" -i "$OVERLAY" -filter_complex '[1:v][0:v]scale2ref[overlay][base]; [base][overlay]overlay' -c:a copy "$NEW_FILENAME"
# adjust timestamp of new merged video to match base video
TIMESTAMP="$(stat --format=%Y "$BASE")"
touch -d "@$TIMESTAMP" "$NEW_FILENAME"
# remove base, overlay, and unused JSON
rm -f "$BASE" "$OVERLAY" "${SNAP%chat_snap.1}json"
COUNT=$((COUNT + 1))
done
fi
printf "\r\033[2K%b Recovered %d snaps\n" "$GOOD" "$TOTAL_FILES"
printf "%b The recovered snaps can be found in '%s'\n" "$NOTICE" "$SNAPS_DIRECTORY"
mv .snaprecovery-tmp/* "$SNAPS_DIRECTORY"
rm -rf .snaprecovery-tmp/