-
-
Notifications
You must be signed in to change notification settings - Fork 75
/
Copy pathpost_dm.py
677 lines (639 loc) · 31.5 KB
/
post_dm.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
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
#coding:utf-8
import urllib
import urllib.request
import http.cookiejar
import json
import time
import os
import sys
import datetime
import time
import ass_maker
import var_set
import _thread
import random
import get_info
import numpy
import get_song_info
path = var_set.path #引入设置路径
roomid = var_set.roomid #引入设置房间号
cookie = var_set.cookie #引入设置cookie
download_api_url = var_set.download_api_url #引入设置的音乐下载链接获取接口
csrf_token = var_set.csrf_token
deviceType = var_set.deviceType
dm_lock = False #弹幕发送锁,用来排队
encode_lock = False #视频渲染锁,用来排队
sensitive_word = ('64', '89') #容易误伤的和谐词汇表,待补充
#检查已使用空间是否超过设置大小
def check_free():
files = os.listdir(path+'/downloads') #获取下载文件夹下所有文件
size = 0
for f in files: #遍历所有文件
size += os.path.getsize(path+'/downloads/'+f) #累加大小
files = os.listdir(path+'/default_mp3')#获取缓存文件夹下所有文件
for f in files: #遍历所有文件
size += os.path.getsize(path+'/default_mp3/'+f)#累加大小
if(size > var_set.free_space*1024*1024): #判断是否超过设定大小
print("space size:"+str(size))
return True
else:
return False
#检查已使用空间,并在超过时,自动删除缓存的视频
def clean_files():
is_boom = True #用来判断可用空间是否爆炸
if(check_free()): #检查已用空间是否超过设置大小
files = os.listdir(path+'/default_mp3') #获取下载文件夹下所有文件
files.sort() #排序文件,以便按日期删除多余文件
for f in files:
if((f.find('.flv') != -1) & (check_free())): #检查可用空间是否依旧超过设置大小,flv文件
del_file_default_mp3(f) #删除文件
elif((f.find('.mp3') != -1) & (check_free())): #检查可用空间是否依旧超过设置大小,mp3文件
del_file_default_mp3(f) #删除文件
del_file_default_mp3(f.replace(".mp3",'')+'.ass')
del_file_default_mp3(f.replace(".mp3",'')+'.info')
elif(check_free() == False): #符合空间大小占用设置时,停止删除操作
is_boom = False
else:
is_boom = False
return is_boom
#删除之前残留的没渲染完的文件
def last_files():
files = os.listdir(path+'/downloads') #获取下载文件夹下所有文件
for f in files:
if f.find('rendering.flv') != -1:
del_file(f) #删除文件
del_file(f.replace('rendering.flv','ok.info'))
del_file(f.replace('rendering.flv','ok.ass'))
elif f.find('.mp4') != -1 or f.find('rendering1') != -1:
del_file(f)
#用于删除文件,防止报错
def del_file(f):
try:
print('delete'+path+'/downloads/'+f)
os.remove(path+'/downloads/'+f)
except:
print('delete error')
last_files()
#用于删除文件,防止报错
def del_file_default_mp3(f):
try:
print('delete'+path+'/default_mp3/'+f)
os.remove(path+'/default_mp3/'+f)
except:
print('delete error')
#下载歌曲,传入参数:
#s:数值型,传入歌曲/mv的id
#t:type,类型,mv或id
#user:字符串型,点播者
#song:歌名,点播时用的关键字,可选
def get_download_url(s, t, user, song = "nothing"):
global encode_lock #视频渲染锁,用来排队
if(clean_files()): #检查空间是否在设定值以内,并自动删除多余视频缓存
send_dm_long('树莓存储空间已爆炸,请联系up')
return
if t == 'id' and var_set.use_gift_check: #检查送过的礼物数量
if check_coin(user, 100) == False:
send_dm_long('用户'+user+'赠送的瓜子不够点歌哦,还差'+str(100-get_coin(user))+'瓜子的礼物')
return
elif t == 'mv' and var_set.use_gift_check:
if check_coin(user, 500) == False:
send_dm_long('用户'+user+'赠送的瓜子不够点mv哦,还差'+str(500-get_coin(user))+'瓜子的礼物')
return
send_dm_long('正在下载'+t+str(s))
print('[log]getting url:'+t+str(s))
try:
filename = str(time.mktime(datetime.datetime.now().timetuple())) #获取时间戳,用来当作文件名
if(t == 'id'): #当参数为歌曲时
#伪装浏览器,防止屏蔽
opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve("http://music.163.com/song/media/outer/url?id="+str(s), path+'/downloads/'+filename+'.mp3') #下载歌曲
lyric_get = urllib.parse.urlencode({'lyric': s}) #格式化参数
lyric_w = urllib.request.urlopen(download_api_url + "?%s" % lyric_get,timeout=5) #设定获取歌词的网址
lyric = lyric_w.read().decode('utf-8') #获取歌词文件
tlyric_get = urllib.parse.urlencode({'tlyric': s}) #格式化参数
tlyric_w = urllib.request.urlopen(download_api_url + "?%s" % tlyric_get,timeout=5) #设定获取歌词的网址
tlyric = tlyric_w.read().decode('utf-8') #获取歌词文件
(song_temp,pic_url) = get_song_info.get_song_info(s)#获取歌曲信息
if song_temp != "":
song = "歌名:"+song_temp
else:
song = "关键词:"+song
if pic_url != "":
try:
#伪装浏览器,防止屏蔽
opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve(pic_url+"?param=200y200", path+'/downloads/'+filename+'.jpg') #下载封面
except Exception as e: #下载出错
print('[log]下载封面出错:'+pic_url)
print(e)
del_file(filename+'.jpg')
ass_maker.make_ass(filename,'当前网易云id:'+str(s)+"\\N"+song+"\\N点播人:"+user,path,lyric,tlyric) #生成字幕
ass_maker.make_info(filename,'id:'+str(s)+","+song+",点播人:"+user,path) #生成介绍信息,用来查询
send_dm_long(t+str(s)+'下载完成,已加入播放队列')
print('[log]已添加排队项目:'+t+str(s))
elif(t == 'mv'): #当参数为mv时
params = urllib.parse.urlencode({t: s}) #格式化参数
f = urllib.request.urlopen(download_api_url + "?%s" % params,timeout=5) #设定获取的网址
url = f.read().decode('utf-8') #读取结果
print('[log]获取'+t+str(s)+'网址:'+url)
#伪装浏览器,防止屏蔽
opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve(url, path+'/downloads/'+filename+'.mp4') #下载mv
print('[log]'+t+str(s)+'下载完成')
if(song == "nothing"): #当直接用id点mv时
ass_maker.make_ass(filename+'ok','当前MV网易云id:'+str(s)+"\\N点播人:"+user,path)#生成字幕
ass_maker.make_info(filename+'ok','MVid:'+str(s)+",点播人:"+user,path)#生成介绍信息,用来查询
else: #当用关键字搜索点mv时
ass_maker.make_ass(filename+'ok','当前MV网易云id:'+str(s)+"\\NMV点播关键词:"+song+"\\N点播人:"+user,path)#生成字幕
ass_maker.make_info(filename+'ok','MVid:'+str(s)+",关键词:"+song+",点播人:"+user,path)#生成介绍信息,用来查询
send_dm_long(t+str(s)+'下载完成,等待渲染')
print('[log]获取'+t+str(s)+'下载完成,等待渲染')
while (encode_lock): #渲染锁,如果现在有渲染任务,则无限循环等待
time.sleep(1) #等待
encode_lock = True #进入渲染,加上渲染锁,防止其他视频一起渲染
send_dm_long(t+str(s)+'正在渲染')
print('[log]获取'+t+str(s)+'正在渲染')
os.system('ffmpeg -threads 1 -i "'+path+'/downloads/'+filename+'.mp4" -aspect 16:9 -vf "scale=1280:720, ass='+path+"/downloads/"+filename+'ok.ass'+'" -c:v libx264 -preset ultrafast -maxrate '+var_set.maxbitrate+'k -tune fastdecode -acodec aac -b:a 192k "'+path+'/downloads/'+filename+'rendering.flv"')
encode_lock = False #关闭渲染锁,以便其他任务继续渲染
del_file(filename+'.mp4') #删除渲染所用的原文件
os.rename(path+'/downloads/'+filename+'rendering.flv',path+'/downloads/'+filename+'ok.flv') #重命名文件,标记为渲染完毕(ok)
send_dm_long(t+str(s)+'渲染完毕,已加入播放队列')
print('[log]获取'+t+str(s)+'渲染完毕,已加入播放队列')
try: #记录日志,已接近废弃
log_file = open(path+'/songs.log', 'a')
log_file.writelines(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) + ','+user+','+t+str(s)+'\r\n')
log_file.close()
except:
print('[error]log error')
except Exception as e: #下载出错
send_dm_long('出错了:请检查命令或重试')
if t == 'id' and var_set.use_gift_check: #归还用掉的瓜子
give_coin(user,100)
elif t == 'mv' and var_set.use_gift_check:
give_coin(user,500)
print('[log]下载文件出错:'+t+str(s))
print(e)
del_file(filename+'.mp3')
del_file(filename+'.mp4')
del_file(filename+'.flv')
#下载歌单
def playlist_download(id,user):
params = urllib.parse.urlencode({'playlist': str(id)}) #格式化参数
f = urllib.request.urlopen(download_api_url + "?%s" % params,timeout=3) #设定获取的网址
try:
playlist = json.loads(f.read().decode('utf-8')) #获取结果,并反序化
if len(playlist['playlist']['tracks'])*100 > get_coin(user) and var_set.use_gift_check:
send_dm_long('用户'+user+'赠送的瓜子不够点'+str(len(playlist['playlist']['tracks']))+
'首歌哦,还差'+str(len(playlist['playlist']['tracks'])*100-get_coin(user))+'瓜子的礼物')
return
else:
send_dm_long('正在下载歌单:'+playlist['playlist']['name']+',共'+str(len(playlist['playlist']['tracks']))+'首')
except Exception as e: #防炸
print('shit(playlist)')
print(e)
send_dm_long('出错了:请检查命令或重试')
for song in playlist['playlist']['tracks']:
print('name:'+song['name']+'id:'+str(song['id']))
get_download_url(song['id'], 'id', user, song['name'])
#下载b站任意视频,传入值:网址、点播人用户名
def download_av(video_url,user):
global encode_lock #视频渲染锁,用来排队
if(clean_files()): #检查空间是否在设定值以内,并自动删除多余视频缓存
send_dm_long('树莓存储空间已爆炸,请联系up')
return
if check_coin(user, 500) == False and var_set.use_gift_check: #扣掉瓜子数
send_dm_long('用户'+user+'赠送的瓜子不够点视频哦,还差'+str(500-get_coin(user))+'瓜子的礼物')
return
try:
v_format = 'flv'
print('[log]downloading bilibili video:'+str(video_url))
video_info = json.loads(os.popen('you-get '+video_url+' --json').read()) #获取视频标题,标题错误则说明点播参数不对,跳到except
video_title = video_info['title'] #获取标题
send_dm_long('正在下载'+video_title)
#send_dm('注意,视频下载十分费时,请耐心等待')
filename = str(time.mktime(datetime.datetime.now().timetuple())) #用时间戳设定文件名
os.system('you-get '+video_url+' -o '+path+'/downloads -O '+filename+'rendering1') #下载视频文件
print('you-get '+video_url+' -o '+path+'/downloads -O '+filename+'rendering1')
if(os.path.isfile(path+'/downloads/'+filename+'rendering1.flv')): #判断视频格式
v_format = 'flv'
elif(os.path.isfile(path+'/downloads/'+filename+'rendering1.mp4')):
v_format = 'mp4'
else:
send_dm_long('视频'+video_title+'下载失败,请重试')
if var_set.use_gift_check:
give_coin(user,500)
return
ass_maker.make_ass(filename+'ok','点播人:'+user+"\\N视频:"+video_title+"\\N"+video_url,path) #生成字幕
ass_maker.make_info(filename+'ok','视频:'+video_title+",点播人:"+user,path) #生成介绍信息,用来查询
send_dm_long('视频'+video_title+'下载完成,等待渲染')
while (encode_lock): #渲染锁,如果现在有渲染任务,则无限循环等待
time.sleep(1) #等待
encode_lock = True #进入渲染,加上渲染锁,防止其他视频一起渲染
send_dm_long('视频'+video_title+'正在渲染')
os.system('ffmpeg -threads 1 -i "'+path+'/downloads/'+filename+'rendering1.'+v_format+'" -aspect 16:9 -vf "scale=1280:720, ass='+path+"/downloads/"+filename+'ok.ass'+'" -c:v libx264 -preset ultrafast -maxrate '+var_set.maxbitrate+'k -tune fastdecode -acodec aac -b:a 192k "'+path+'/downloads/'+filename+'rendering.flv"')
encode_lock = False #关闭渲染锁,以便其他任务继续渲染
del_file(filename+'rendering1.'+v_format) #删除渲染所用的原文件
os.rename(path+'/downloads/'+filename+'rendering.flv',path+'/downloads/'+filename+'ok.flv') #重命名文件,标记为渲染完毕(ok)
send_dm_long('视频'+video_title+'渲染完毕,已加入播放队列')
except: #报错提示,一般只会出现在获取标题失败时出现,就是点播参数不对
send_dm_long('出错了:请检查命令或重试')
if var_set.use_gift_check:
give_coin(user,500)
#搜索歌曲并下载
def search_song(s,user):
print('[log]searching song:'+s)
params = urllib.parse.urlencode({'type': 1, 's': s}) #格式化参数
f = urllib.request.urlopen("http://s.music.163.com/search/get/?%s" % params,timeout=3) #设置接口网址
search_result = json.loads(f.read().decode('utf-8')) #获取结果
result_id = search_result["result"]["songs"][0]["id"] #提取歌曲id
_thread.start_new_thread(get_download_url, (result_id, 'id', user,s)) #扔到下载那里下载
#搜索mv并下载
def search_mv(s,user):
url = "http://music.163.com/api/search/get/"
postdata =urllib.parse.urlencode({
's':s,
'offset':'1',
'limit':'10',
'type':'1004'
}).encode('utf-8')
header = {
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding":"utf-8",
"Accept-Language":"zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3",
"Connection":"keep-alive",
"Host":"music.163.com",
"Referer":"http://music.163.com/",
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0"
}
req = urllib.request.Request(url,postdata,header) #设置接口网址
result = json.loads(urllib.request.urlopen(req,timeout=3).read().decode('utf-8')) #获取结果
result_id = result['result']['mvs'][0]['id'] #提取mv id
_thread.start_new_thread(get_download_url, (result_id, 'mv', user,s)) #扔到下载那里下载
#获取赠送过的瓜子数量
def get_coin(user):
gift_count = 0
try:
gift_count = numpy.load('users/'+user+'.npy')
except:
gift_count = 0
return gift_count
#扣除赠送过的瓜子数量
def take_coin(user, take_sum):
gift_count = 0
try:
gift_count = numpy.load('users/'+user+'.npy')
except:
gift_count = 0
gift_count = gift_count - take_sum
try:
numpy.save('users/'+user+'.npy', gift_count)
except:
print('create error')
#检查并扣除指定数量的瓜子
def check_coin(user, take_sum):
if get_coin(user) >= take_sum:
take_coin(user, take_sum)
return True
else:
return False
#给予赠送过的瓜子数量
def give_coin(user, give_sum):
gift_count = 0
try:
gift_count = numpy.load('users/'+user+'.npy')
except:
gift_count = 0
gift_count = gift_count + give_sum
try:
numpy.save('users/'+user+'.npy', gift_count)
except:
print('create error')
def check_night():
print(time.localtime()[3])
if (time.localtime()[3] >= 22 or time.localtime()[3] <= 5) and var_set.play_videos_when_night:
send_dm_long('现在是晚间专场哦~命令无效')
return True
#切歌请求次数统计
jump_to_next_counter = 0
rp_lock = False
def pick_msg(s, user):
global jump_to_next_counter #切歌请求次数统计
global encode_lock #视频渲染任务锁
global rp_lock
if ((user=='晨旭') | (user=='摘希喵喵喵') | (user=='王老菊未来科技种植园')): #debug使用,请自己修改
if(s=='锁定'):
rp_lock = True
send_dm_long('已锁定点播功能,不响应任何弹幕')
if(s=='解锁'):
rp_lock = False
send_dm_long('已解锁点播功能,开始响应弹幕请求')
if(s=='清空列表'):
if(encode_lock):
send_dm_long('有渲染任务,无法清空')
return
#获取目录下所有文件
for i in os.listdir(path+'/downloads'):
del_file(i)
os.system('killall ffmpeg')
send_dm_long('已经清空列表~')
if((user == '接待喵') | rp_lock): #防止自循环
return
#下面的不作解释,很简单一看就懂
if(s.find('mvid+') == 0):
if check_night():
return
send_dm_long('已收到'+user+'的指令')
s = s.replace(' ', '') #剔除弹幕中的所有空格
_thread.start_new_thread(get_download_url, (s.replace('mvid+', '', 1), 'mv',user))
elif (s.find('mv+') == 0):
if check_night():
return
try:
send_dm_long('已收到'+user+'的指令')
search_mv(s.replace('mv+', '', 1),user)
except:
print('[log]mv not found')
send_dm_long('出错了:没这mv')
elif (s.find('song+') == 0):
if check_night():
return
try:
send_dm_long('已收到'+user+'的指令')
search_song(s.replace('song+', '', 1),user)
except:
print('[log]song not found')
send_dm_long('出错了:没这首歌')
elif (s.find('id+') == 0):
if check_night():
return
send_dm_long('已收到'+user+'的指令')
s = s.replace(' ', '') #剔除弹幕中的所有空格
_thread.start_new_thread(get_download_url, (s.replace('id+', '', 1), 'id',user))
elif(s.find('mvid') == 0):
if check_night():
return
send_dm_long('已收到'+user+'的指令')
s = s.replace(' ', '') #剔除弹幕中的所有空格
_thread.start_new_thread(get_download_url, (s.replace('mvid', '', 1), 'mv',user))
elif (s.find('mv') == 0):
if check_night():
return
try:
send_dm_long('已收到'+user+'的指令')
search_mv(s.replace('mv', '', 1),user)
except:
print('[log]mv not found')
send_dm_long('出错了:没这mv')
elif (s.find('song') == 0):
if check_night():
return
try:
send_dm_long('已收到'+user+'的指令')
search_song(s.replace('song', '', 1),user)
except:
print('[log]song not found')
send_dm_long('出错了:没这首歌')
elif (s.find('id') == 0):
if check_night():
return
send_dm_long('已收到'+user+'的指令')
s = s.replace(' ', '') #剔除弹幕中的所有空格
_thread.start_new_thread(get_download_url, (s.replace('id', '', 1), 'id',user))
elif (s.find('点歌') == 0):
if check_night():
return
try:
send_dm_long('已收到'+user+'的指令')
search_song(s.replace('点歌', '', 1),user)
except:
print('[log]song not found')
send_dm_long('出错了:没这首歌')
elif (s.find('喵') > -1):
replay = ["喵??", "喵喵!", "喵。。喵?", "喵喵喵~", "喵!"]
send_dm_long(replay[random.randint(0, len(replay)-1)]) #用于测试是否崩掉
elif (s == '切歌'): #切歌请求
if(encode_lock): #切歌原理为killall ffmpeg,但是如果有渲染任务,kill后也会结束渲染进程,会出错
send_dm_long('有渲染任务,无法切歌')
return
jump_to_next_counter += 1 #切歌次数统计加一
if((user=='晨旭') | (user=='摘希喵喵喵')): #debug使用,请自己修改
jump_to_next_counter=5
if(jump_to_next_counter < 5): #次数未达到五次
send_dm_long('已收到'+str(jump_to_next_counter)+'次切歌请求,达到五次将切歌')
else: #次数达到五次
jump_to_next_counter = 0 #次数统计清零
send_dm_long('已执行切歌动作')
os.system('killall ffmpeg') #强行结束ffmpeg进程
elif ((s == '点播列表') or (s == '歌曲列表')):
if check_night():
return
send_dm_long('已收到'+user+'的指令,正在查询')
files = os.listdir(path+'/downloads') #获取目录下所有文件
files.sort() #按文件名(下载时间)排序
songs_count = 0 #项目数量
all_the_text = ""
for f in files:
if((f.find('.mp3') != -1) and (f.find('.download') == -1)): #如果是mp3文件
try:
info_file = open(path+'/downloads/'+f.replace(".mp3",'')+'.info', 'r') #读取相应的info文件
all_the_text = info_file.read()
info_file.close()
except Exception as e:
print(e)
if(songs_count < 10):
send_dm_long(all_the_text)
songs_count += 1
if((f.find('ok.flv') != -1) and (f.find('.download') == -1) and (f.find('rendering') == -1)):#如果是有ok标记的flv文件
try:
info_file = open(path+'/downloads/'+f.replace(".flv",'')+'.info', 'r') #读取相应的info文件
all_the_text = info_file.read()
info_file.close()
except Exception as e:
print(e)
if(songs_count < 10):
send_dm_long(all_the_text)
songs_count += 1
if(songs_count <= 10):
send_dm_long('点播列表展示完毕,一共'+str(songs_count)+'个')
else:
send_dm_long('点播列表前十个展示完毕,一共'+str(songs_count)+'个')
elif (s == '渲染列表'):
if check_night():
return
send_dm_long('已收到'+user+'的指令,正在查询')
files = os.listdir(path+'/downloads') #获取目录下所有文件
files.sort() #按文件名(下载时间)排序
songs_count = 0 #项目数量
all_the_text = ""
for f in files:
if(f.find('rendering1.flv') != -1): #如果是没有ok标记的flv文件
try:
info_file = open(path+'/downloads/'+f.replace("rendering1.flv",'')+'ok.info', 'r') #读取相应的info文件
all_the_text = info_file.read()
info_file.close()
except Exception as e:
print(e)
if(songs_count < 5):
send_dm_long(all_the_text)
songs_count += 1
if(f.find('.mp4') != -1): #如果是mp4文件
try:
info_file = open(path+'/downloads/'+f.replace(".mp4",'')+'ok.info', 'r') #读取相应的info文件
all_the_text = info_file.read()
info_file.close()
except Exception as e:
print(e)
if(songs_count < 5):
send_dm_long(all_the_text)
songs_count += 1
if(songs_count <= 5):
send_dm_long('渲染列表展示完毕,一共'+str(songs_count)+'个')
else:
send_dm_long('渲染列表前5个展示完毕,一共'+str(songs_count)+'个')
elif (s.find('av') == 0):
if check_night():
return
s = s.replace(' ', '') #剔除弹幕中的所有空格
try:
if(s.find('p') == -1):
send_dm_long('已收到'+user+'的指令')
#视频网址格式:https://www.bilibili.com/video/avxxxxx
ture_url=s.replace('av','https://www.bilibili.com/video/av')
_thread.start_new_thread(download_av, (ture_url,user))
else:
send_dm_long('已收到'+user+'的指令')
#视频网址格式:https://www.bilibili.com/video/avxxxx/#page=x
ture_url=s.replace('p','/#page=')
ture_url=ture_url.replace('av','https://www.bilibili.com/video/av')
_thread.start_new_thread(download_av, (ture_url,user))
except:
print('[log]video not found')
elif (s.find('温度') > -1 and deviceType == "pi"):
#send_dm_long("CPU "+os.popen('vcgencmd measure_temp').readline()) #读取命令行得到的温度
send_dm_long(get_info.getInfo())
elif (s.find('歌单') == 0):
if check_night():
return
send_dm_long('已收到'+user+'的指令')
s = s.replace(' ', '') #剔除弹幕中的所有空格
_thread.start_new_thread(playlist_download, (s.replace('歌单', '', 1),user))
elif (s.find('查询') == 0):
send_dm_long(user+'的瓜子余额还剩'+str(get_coin(user))+'个')
# else:
# print('not match anything')
#发送弹幕函数,通过post完成,具体可以自行使用浏览器,进入审查元素,监控network选项卡研究
def send_dm(s):
global cookie
global roomid
global dm_lock
global csrf_token
while (dm_lock):
#print('[log]wait for send dm')
time.sleep(1)
dm_lock = True
try:
url = "https://api.live.bilibili.com/msg/send"
postdata =urllib.parse.urlencode({
'color':'16777215',
'fontsize':'25',
'mode':'1',
'msg':s,
'rnd':str(int(time.time())),
'roomid':roomid,
'csrf_token':csrf_token,
'csrf':csrf_token
}).encode('utf-8')
header = {
"Accept":"application/json, text/javascript, */*; q=0.01",
"Accept-Encoding":"utf-8",
"Accept-Language":"zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3",
"Connection":"keep-alive",
"Cookie":cookie,
"Host":"api.live.bilibili.com",
"Referer":"https://live.bilibili.com/"+roomid,
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 Vivaldi/2.2.1388.37"
}
req = urllib.request.Request(url,postdata,header)
dm_result = json.loads(urllib.request.urlopen(req,timeout=3).read().decode('utf-8'))
if len(dm_result['msg']) > 0:
print('[error]弹幕发送失败:'+s)
print(dm_result)
else:
print('[log]发送弹幕:'+s)
except Exception as e:
print('[error]send dm error')
print(e)
time.sleep(1.5)
dm_lock = False
#每条弹幕最长只能发送20字符,过长的弹幕分段发送
def send_dm_long(s):
n=var_set.dm_size
for hx in sensitive_word: #处理和谐词,防止点播机的回复被和谐
if (s.find(hx) > -1):
s = s.replace(hx, hx[0]+"-"+hx[1:]) #在和谐词第一个字符后加上一个空格
for i in range(0, len(s), n):
send_dm(s[i:i+n])
#获取原始弹幕数组
#本函数不作注释,具体也请自己通过浏览器审查元素研究
def get_dm():
global temp_dm
global roomid
global csrf_token
url = "http://api.live.bilibili.com/ajax/msg"
postdata =urllib.parse.urlencode({
'token:':'',
'csrf_token:':csrf_token,
'roomid':roomid
}).encode('utf-8')
header = {
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Encoding":"utf-8",
"Accept-Language":"zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3",
"Connection":"keep-alive",
"Host":"api.live.bilibili.com",
"Referer":"http://live.bilibili.com/"+roomid,
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:32.0) Gecko/20100101 Firefox/32.0"
}
req = urllib.request.Request(url,postdata,header)
dm_result = json.loads(urllib.request.urlopen(req,timeout=1).read().decode('utf-8'))
#for t_get in dm_result['data']['room']:
#print('[log]['+t_get['timeline']+']'+t_get['nickname']+':'+t_get['text'])
return dm_result
#检查某弹幕是否与前一次获取的弹幕数组有重复
def check_dm(dm):
global temp_dm
for t_get in temp_dm['data']['room']:
if((t_get['text'] == dm['text']) & (t_get['timeline'] == dm['timeline'])):
return False
return True
#弹幕获取函数,原理为不断循环获取指定直播间的初始弹幕,并剔除前一次已经获取到的弹幕,余下的即为新弹幕
def get_dm_loop():
global temp_dm
temp_dm = get_dm()
while True:
dm_result = get_dm()
for t_get in dm_result['data']['room']:
if(check_dm(t_get)):
print('[log]['+t_get['timeline']+']'+t_get['nickname']+':'+t_get['text'])
#send_dm('用户'+t_get['nickname']+'发送了'+t_get['text']) #别开,会死循环
text = t_get['text']
pick_msg(text,t_get['nickname']) #新弹幕检测是否匹配为命令
temp_dm = dm_result
time.sleep(1)
def test():
print('ok')
print('程序已启动,连接房间id:'+roomid)
send_dm_long('弹幕监控已启动,可以点歌了')
# while True: #防炸
# try:
# get_dm_loop() #开启弹幕获取循环函数
# except Exception as e: #防炸
# print('shit')
# print(e)
# dm_lock = False #解开弹幕锁,以免因炸了而导致弹幕锁没解开,进而导致一直锁着发不出弹幕