File size: 4,805 Bytes
f9ec799
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import os.path
import random

from musicdl import musicdl
from musicdl.modules import Downloader
from pydub import AudioSegment
from yt_dlp import YoutubeDL
import yt_dlp
from yt_dlp.utils import download_range_func
import json


def is_integer(string):
    if string.isdigit():
        return int(string)
    else:
        return 0


def is_numeric(string):
    if string.isdigit():
        return True
    if string.count('.') == 1:
        integer_part, decimal_part = string.split('.')
        if integer_part.isdigit() and decimal_part.isdigit():
            return True
    return False


def time_to_seconds(time_string):
    hours, minutes, seconds = map(lambda x: is_integer(x), time_string.split(':'))
    total_seconds = hours * 3600 + minutes * 60 + seconds
    return total_seconds


def size_to_int(size_string):
    prefix_size_str = size_string[:-2]  # 去除最后的单位部分,转换为浮点数
    if not is_numeric(prefix_size_str):
        return 5.1 * 1024 * 1024
    unit = size_string[-2:]  # 获取单位部分
    size = float(prefix_size_str)
    if unit == 'KB':
        size *= 1024  # 转换为字节
    elif unit == 'MB':
        size *= 1024 * 1024
    elif unit == 'GB':
        size *= 1024 * 1024 * 1024
    elif unit == 'TB':
        size *= 1024 * 1024 * 1024 * 1024

    return int(size)  # 转换为整数


def search_youtube(keywords):
    YDL_OPTIONS = {
        'format': 'bestaudio',
        # 'noplaylist': 'True',
        # 'proxy': 'http://127.0.0.1:8889',
    }
    with YoutubeDL(YDL_OPTIONS) as ydl:
        video = ydl.extract_info(f"ytsearch:{keywords}", download=False)['entries'][0:5]
        # video = ydl.extract_info(keywords, download=False)
    if len(video) > 0:
        ret = random.choice(video)
        return ydl.sanitize_info(ret)
    else:
        return None


def download_youtube(info, save_path):
    url = info['original_url']
    duration = info['duration']


    start_second = 0
    end_second = duration
    
    ydl_opts = {
        'format': 'm4a/bestaudio/best',
        'downloader': 'ffmpeg',
        'download_ranges': download_range_func(None, [(start_second, end_second)]),
        # ℹ️ See help(yt_dlp.postprocessor) for a list of available Postprocessors and their arguments
        'postprocessors': [{  # Extract audio using ffmpeg
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
        }],
        'outtmpl': save_path,
        # 'proxy': 'http://127.0.0.1:8889',
    }
    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=True)
        # ℹ️ ydl.sanitize_info makes the info json-serializable
        ret_info = ydl.sanitize_info(info)
        ret_info['save_path'] = save_path
        return ret_info


def get_youtube(keywords, save_path):
    info = search_youtube(keywords)
    if info is None:
        return
    else:
        download_youtube(info, save_path)


def get_albums(keywords, config):
    target_srcs = [
        'kugou', 'kuwo', 'qqmusic', 'qianqian', 'fivesing',
        'netease', 'migu', 'joox', 'yiting',
    ]
    client = musicdl.musicdl(config=config)
    results = client.search(keywords, target_srcs)
    albums_set = set()
    valid_albums = []
    for albums in results.values():
        if len(albums) == 0:
            continue
        for album in albums:
            if album['songname'] in albums_set:
                continue
            if album['ext'] != 'mp3':
                continue
            if size_to_int(album['filesize']) > 5 * 1024 * 1024:
                continue
            if time_to_seconds(album['duration']) > 300:
                continue
            else:
                albums_set.add(album['songname'])
                valid_albums.append(album)
    return valid_albums


def get_random_spit(songinfo, save_path):
    d = Downloader(songinfo)
    d.start()
    song = AudioSegment.from_mp3(save_path)
    # pydub does things in milliseconds
    length = len(song)
    left_idx = length / 2 - 15 * 1000
    right_idx = length / 2 + 15 * 1000
    if left_idx < 0:
        left_idx = 0
    if right_idx > length:
        right_idx = length
    middle_30s = song[left_idx:right_idx]
    middle_30s.export(save_path, format="wav")
    return save_path


def download_random(keywords, config, save_path):
    albums = get_albums(keywords, config)
    if len(albums) == 0:
        return None
    album = random.choice(albums)
    get_random_spit(album, save_path=save_path)


if __name__ == '__main__':
    # config = {'logfilepath': 'musicdl.log', 'downloaded': 'downloaded', 'search_size_per_source': 5, 'proxies': {}}
    # infos = get_albums('李荣浩', config)
    # print(infos)
    info = search_youtube('李荣浩 模特')
    download_youtube(info, "downloaded/模特")