Skip to content

Instantly share code, notes, and snippets.

@tigerwang202
Forked from scturtle/addlrc.py
Last active November 7, 2015 13:47
Show Gist options
  • Save tigerwang202/ba16e5a31e0da3c307cc to your computer and use it in GitHub Desktop.
Save tigerwang202/ba16e5a31e0da3c307cc to your computer and use it in GitHub Desktop.
import eyed3
import re
import glob
def get_lyric(lrc):
text = open(lrc).read()
text = re.sub(r'(?:\[.*\])+', '', text).strip()
text = map(lambda l: l.strip(), text.split('\n'))
ans = []
for l in text:
if not ans or ans[-1]!=l:
ans.append(l)
return '\n'.join(ans)
if __name__ == '__main__':
for lrc in glob.glob('*.lrc'):
f = eyed3.load(lrc.split('.')[0] + '.mp3')
f.tag.lyrics.set(get_lyric(lrc).decode('utf8'))
f.tag.save()
print lrc, 'OK'
# -*- coding: utf-8 -*-
#! /usr/bin/env python
# https://gist.github.com/tigerwang202/ba16e5a31e0da3c307cc
import re
import os
import sys
import md5
import json
import random
import requests
ENCODE = 'gbk' if sys.platform.startswith('win') else 'utf8'
CMD = 'curl -# -o "{name}" "{url}"'
SEARCH = 'http://music.163.com/api/search/get/web'
DETAIL = 'http://music.163.com/api/song/detail/?ids=[{}]'
LRC = 'http://music.163.com/api/song/media?id={}'
HEADERS = {'Referer': 'http://music.163.com'}
MP3 = 'http://m{}.music.126.net/{}/{}.mp3'
DEST = 'E:\CloudMusic'
class Json:
def __repr__(self):
return json.dumps(self.json, indent=2)
def json2obj(json):
if isinstance(json, dict):
obj = Json()
setattr(obj, 'json', json)
for k, v in json.items():
k = k.replace(' ', '_')
setattr(obj, k, json2obj(v))
return obj
if isinstance(json, list):
return map(json2obj, json)
return json
def search(q, tp=1):
'''
>>> search('2375').result.songs[0].id
365613
'''
return json2obj(requests.post(SEARCH, headers=HEADERS,
data=dict(type=tp, s=q, offset=0,
limit=30, total='true')
).json())
def searchAlbum(q):
return search(q, tp=10)
def searchArtist(q):
return search(q, tp=100)
def detail(sids):
'''
>>> detail([365613]).songs[0].name
u'2375'
'''
return json2obj(requests.get(DETAIL.format(','.join(map(str, sids))),
headers=HEADERS).json())
def url_2_sids(url):
'''
>>> url_2_sids('http://music.163.com/#/album?id=36197')
['365612', '365613', '365614', '365615', '365617']
'''
_id = url.split('=')[1]
if 'song?id' in url:
return [_id]
else:
r = requests.get(url.replace('/#/', '/'), headers=HEADERS)
return re.findall(r'song\?id=(\d+)', r.content)
def encrypted_id(id):
''' from https://github.com/yanunon/NeteaseCloudMusic '''
byte1 = bytearray('3go8&$8*3*3h0k(2)2')
byte2 = bytearray(id)
byte1_len = len(byte1)
for i in xrange(len(byte2)):
byte2[i] = byte2[i] ^ byte1[i % byte1_len]
m = md5.new()
m.update(byte2)
result = m.digest().encode('base64')[:-1]
result = result.replace('/', '_')
result = result.replace('+', '-')
return result
def download(sids, withlrc=False):
'''
>>> dfsId = str(detail([365613]).songs[0].bMusic.dfsId)
>>> MP3.format(1, encrypted_id(dfsId), dfsId)
'http://m1.music.126.net/n5usuzBfOxdzcGGnF_2hnQ==/2781764418296774.mp3'
'''
json = detail(sids)
for i in json.songs:
'''
name = ''
for c in i.name:
try:
name += c.encode(ENCODE)
except:
pass
artist = ''
for c in i.artists[0].name:
try:
artist += c.encode(ENCODE)
except:
pass
'''
name = i.name.encode(ENCODE)
artist = i.artists[0].name.encode(ENCODE)
# url = i.mp3Url
mp3file = os.path.join(DEST, artist + ' - ' + name + '.mp3')
if os.path.exists(mp3file):
print 'song {} exist, skip.'.format(mp3file)
continue
dfsId = str(i.bMusic.dfsId)
url = MP3.format(random.randrange(1, 3), encrypted_id(dfsId), dfsId)
print artist, name, url
cc = os.system(CMD.format(name=mp3file, url=url))
# assert not cc, 'Interrupted'
if cc:
print 'download error, skip...'
if os.path.exists(mp3file):
os.remove(mp3file)
continue
if withlrc:
lrc = requests.get(LRC.format(i.id), headers=HEADERS).json()
lrc = json2obj(lrc)
if hasattr(lrc, 'lyric'):
lrcfile = os.path.join(DEST, artist + ' - ' + name + '.lrc')
open(lrcfile, 'w').write(lrc.lyric.encode('utf-8'))
def main():
if len(sys.argv) != 2:
print 'Usage: download_music_from_163 url'
print 'url: song or album \'s page url.'
exit(1)
else:
param = sys.argv[1]
if param.startswith('http'):
songids = url_2_sids(param)
download(songids)
elif param.endswith('.txt'):
''' batch download from urls in txt file '''
with open(param, 'r') as f:
lines = f.readlines()
for url in lines:
if url.startswith('http'):
songids = url_2_sids(url)
download(songids)
f.close()
else:
print 'unknown param, quit!'
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment