aboutsummaryrefslogtreecommitdiff
path: root/bulk-audio/get
blob: 196a5d5802533d2a8513f8cc2a5ca069eb95248c (plain)
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
#!/bin/sh

SCRIPT_NAME="$0"
SOURCES="local_audio,lp101,lp101_alt,jisho,nhk"
KANJI=""
KANA=""

urlencode() {
	printf '%s' "$1" | od -An -tx1 | tr ' ' '%' | tr '[:lower:]' '[:upper:]'
}

normalize_kana() {
	sed 'y/テデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅ/てでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづ/'
}

local_audio() {
	URL="http://localhost:5050/"
	res="$(curl -sLGo - "$URL" --data-urlencode "term=$KANJI" --data-urlencode "reading=$(echo "$KANA" | normalize_kana)")"
	[ $? -ne 0 ] && return
	URL="$(echo "$res" | jq --raw-output '.audioSources[0].url // empty')"
	[ -z "$URL" ] && return
	curl -sLo - "$URL" | ffmpeg -hide_banner -loglevel error -i pipe: -f mp3 pipe:
	exit 0
}

lp101() {
  URL="https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=$KANJI&kana=$KANA"
  # 52288 is the content-length of the "the audio for this clip is currently
  # not available. it will be recorded and uploaded shortly. thank you for your
  # patience" message (404, but server sends 200 anyways)
  curl -X HEAD -iso - "$URL" | awk '/^Content-length:/ { exit $2 == 52288 }'
	[ $? -ne 0 ] && return
	curl -sLo - "$URL"
	exit 0
}

lp101_alt() {
	HTML="$(curl -s -X POST \
		"https://www.japanesepod101.com/learningcenter/reference/dictionary_post" \
		-H "Content-Type: application/x-www-form-urlencoded" \
		-d "post=dictionary_reference&match_type=exact&search_query=$KANJI&vulgar=true" \
	)"
	[ $? -ne 0 ] && return
	URL="$(echo "$HTML" | pup "audio source attr{src}" | head -n1)"
	[ -z "$URL" ] && return
	curl -sLo - "$URL"
	exit 0
}

jisho() {
	HTML="$(curl -s "https://jisho.org/search/$KANJI")"
	[ $? -ne 0 ] && return
	URL="$(echo "$HTML" | pup "audio[id=\"audio_$KANJI:$KANA\"] source attr{src}" | head -n1)"
	[ -z "$URL" ] && return
	curl -sLo - "https:$URL"
	exit 0
}

nhk() {
	BASE_URL="https://sakura-paris.org"
	HTML="$(curl -s "$BASE_URL/dict/NHK日本語発音アクセント辞典/prefix/$KANJI")"
	[ $? -ne 0 ] && return
	URL="$(echo "$HTML" | pup "#$(urlencode $KANJI) audio source[src\$=\".mp3\"] attr{src}" | head -n1)"
	[ -z "$URL" ] && return
	curl -sLo - "$BASE_URL$URL"
	exit 0
}

usage() {
	cat << EOF
usage: $SCRIPT_NAME [OPTIONS] <KANJI> <KANA> > <OUTPUT>

attempt to download a native Japanese recording of word written as KANJI and
read as KANA. outputs mp3 to stdout. return value is 0 if OUTPUT was written
(clip was found), and 1 if no clip could be found.

options:
	-s <source1[,source2,...]>    set source order (default: $SOURCES)
	-h                            show help

sources:
	local        TheMoeWay local-audio-yomichan server
	lp101        JapanesePod101
	lp101_alt    JapanesePod101 (Alternate)
	jisho        Jisho.org
	nhk          NHK日本語発音アクセント辞典
EOF
	exit ${1:-0}
}

while getopts 'hs:' OPT; do
	case "$OPT" in
		h) usage ;;
		s) SOURCES="$OPTARG" ;;
		\?|*) usage 1 ;;
	esac
done

shift $(($OPTIND - 1))
[ $# -ne 2 ] && usage 1 >&2

KANJI="$1"
KANA="$2"

$(printf '%s;' "$SOURCES" | sed -z 's/[;,\n]/ ; /g')

# if none were succesful, delete output file and exit with error
rm -f "$OUTPUT"
exit 1