-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
106 lines (88 loc) · 2.98 KB
/
app.py
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
import os
import sys
from utils import *
from api import *
from db import *
import ffmpeg
import re
import json
from mutagen.easyid3 import EasyID3
from mutagen.id3 import ID3, APIC
from sanitize_filename import sanitize
LOUDNORM_REGEX = re.compile(r'({.+?})\s*$', re.M | re.S)
def process_media(media):
bvid = media['bvid']
video_info = get_video_info(bvid)
authors = []
if 'staff' in video_info:
authors = list(map(lambda s: s['name'], video_info['staff']))
else:
authors = [video_info['owner']['name']]
cover_url = video_info['pic']
audio_urls = get_play_url(bvid, video_info['pages'][0]['cid'])[
'dash']['audio']
audio_url_best = sorted(audio_urls, key=lambda x: x['bandwidth'], reverse=True)[
0]['baseUrl']
src_file = f"data/{bvid}.m4s"
download_file(audio_url_best, src_file)
cover_file = f"data/{bvid}.jpg"
cover_out_file = f"data/{bvid}_crop.jpg"
download_file(cover_url, cover_file)
sanitized_title = sanitize(sanitize(media['title']))
out_file = f"data/{sanitized_title}.mp3"
print(out_file)
loudnorm_args = {
'i': -16, 'lra': 9, 'tp': -1
}
pass1_output = ffmpeg.input(src_file)\
.filter('loudnorm', print_format='json', **loudnorm_args)\
.output("", f="null")\
.run(capture_stderr=True)[1].decode('utf-8')
matches = LOUDNORM_REGEX.search(pass1_output)
if (matches is None):
raise RuntimeError("No output found in stderr")
pass1_result = json.loads(matches.group(1))
ffmpeg.input(src_file).audio\
.filter(
'loudnorm',
measured_i=pass1_result['input_i'],
measured_lra=pass1_result['input_lra'],
measured_tp=pass1_result['input_tp'],
measured_thresh=pass1_result['input_thresh'],
**loudnorm_args,
)\
.output(out_file, ab='320k', ar=48000)\
.run(overwrite_output=True)
ffmpeg.input(cover_file).video\
.filter('scale', 'if(gt(iw,ih),-1,300)', 'if(gt(iw,ih),300,-1)')\
.filter('crop', 300, 300, exact=1)\
.output(cover_out_file)\
.run(overwrite_output=True, quiet=True)
tags = EasyID3(out_file)
tags["title"] = media['title']
tags["album"] = media['title']
tags["artist"] = authors
tags.save()
tags = ID3(out_file)
tags.delall("APIC")
with open(cover_out_file, 'rb') as art:
tags.add(APIC(
encoding=3,
mime='image/jpeg',
type=3, desc=u'Cover',
data=art.read()
))
tags.save()
os.unlink(src_file)
os.unlink(cover_file)
os.unlink(cover_out_file)
if __name__ == '__main__':
LIST_ID = os.environ.get('BILI_LIST_ID')
if LIST_ID is None:
print("请用 BILI_LIST_ID 环境变量提供收藏夹ID", file=sys.stderr)
sys.exit(1)
for media in get_playlist(LIST_ID)['medias']:
if query_record(media['bvid']):
continue
process_media(media)
add_record(media['bvid'])