├── LiveRecorder ├── .gitignore ├── liverecorder.sh └── videos │ ├── video_fix.py │ └── wait_upload │ ├── delete.sh │ └── upload.sh ├── README.md └── VideoDownloader └── download.py /LiveRecorder/.gitignore: -------------------------------------------------------------------------------- 1 | *.flv -------------------------------------------------------------------------------- /LiveRecorder/liverecorder.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # bash liverecorder.sh [ROOMID] [DIR] [DOWNLOAD_SPEED] 4 | 5 | roomid=$1 6 | echo "直播间号为:$1" 7 | echo "查询空间目录:$2" 8 | echo "下载限速 $3 kb" 9 | #mkdir $roomid 10 | while (true) 11 | DISK=`df -l | grep "$2" | awk '{print $4}'` 12 | 13 | if [ "$DISK" -lt "10240" ]; then 14 | echo "磁盘空间不足, only $DISK bytes" 15 | date 16 | sleep 60 17 | continue 18 | else 19 | echo "磁盘空间充足, $DISK bytes" 20 | fi 21 | do 22 | trickle -d $3 you-get -O "$roomid"_`date +%Y%m%d_%T` -o videos https://live.bilibili.com/$roomid 2>/dev/null 23 | shuf -i 30-60 -n 1 | xargs sleep 24 | done -------------------------------------------------------------------------------- /LiveRecorder/videos/video_fix.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3.6 2 | import os 3 | import sys 4 | import time 5 | import traceback 6 | 7 | # 1. 获取所有的文件为old_files 8 | # 2. 已经处理过的放在white_list 9 | # 3. 每次执行检测now_files,就是当前满足条件的 10 | # old_files = set(os.listdir(os.getcwd())) # 0, A, B, C 11 | 12 | # now_files = set() # 13 | 14 | 15 | white_list = set([sys.argv[0], 'wait_upload']) # 0 16 | # old_filis = white_list 17 | old_files = set() 18 | 19 | 20 | def convert(files): 21 | for i in files: 22 | fname = i 23 | if i[-4:] != '.flv': 24 | continue 25 | if os.path.getsize(fname) == 0: 26 | print('{fname}大小为0, 删除'.format(fname=fname)) 27 | os.popen('rm -f {fname}'.format(fname=fname)) 28 | continue 29 | new_fname = fname.replace(':', '').replace('.flv', '_.flv') 30 | shell = 'yamdi -i %s -o wait_upload/%s' % (fname, new_fname) 31 | print(shell) 32 | print(os.popen('yamdi -i %s -o wait_upload/%s' % (fname, new_fname)).read(), end='') 33 | try: 34 | new_file_size = os.path.getsize(f'wait_upload/{new_fname}') / 1024 / 1024 # M 35 | old_file_size = os.path.getsize(f'{fname}') / 1024 / 1024 # M 36 | print(f' {old_file_size}M =>> {new_file_size}M') 37 | if 0.9 <= old_file_size / new_file_size <= 1.1: 38 | print(os.popen('rm -f %s' % fname).read(), end='') 39 | else: 40 | print(os.popen(f'rm -f wait_upload/{new_fname}').read(), end='') 41 | wrong_name = fname.replace(':', '').replace('.flv', '_wrong.flv') 42 | ###### 43 | new_mp4_file_name = fname.replace(':', '') + '.mp4' 44 | shell = f'ffmpeg -i {fname} -c copy -f mp4 wait_upload/{new_mp4_file_name}' 45 | print(os.popen(shell).read(), end='') 46 | 47 | new_file_size_mp4 = os.path.getsize(f'wait_upload/{new_mp4_file_name}') / 1024 / 1024 48 | if 0.9 <= old_file_size / new_file_size_mp4 <= 1.1: 49 | print(f'{fname}.mp4 is ok!!!') 50 | else: 51 | shell = f'rm -f wait_upload/{new_mp4_file_name}' 52 | print(os.popen(shell).read(), end='') 53 | 54 | ############ 55 | print(f'mv {fname} wait_upload/{wrong_name}') 56 | print(os.popen(f'mv {fname} wait_upload/{wrong_name}').read(), end='') 57 | white_list.add(i) 58 | except Exception as e: 59 | traceback.print_exc() 60 | # print(os.popen('mv %s tmp' % fname).read(), end='') 61 | # white_list.add(i) # A, B, C, 0 62 | # delete 63 | 64 | 65 | if not os.path.exists('wait_upload'): 66 | os.mkdir('wait_upload') 67 | 68 | while 1: 69 | now_files = set(os.listdir(os.getcwd())) # A, B, C, 0 70 | now_files -= white_list # 白名单不处理 71 | old_files = set() 72 | for f in now_files: 73 | if not f.endswith('.flv'): 74 | continue 75 | # 检测到5min无变化的flv文件 76 | if time.time() - os.path.getmtime(f) > 60 * 5: 77 | old_files.add(f) 78 | break 79 | 80 | # if old_files: 81 | # print('now', now_files) 82 | # now_files -= white_list 83 | # print('now', now_files) 84 | # old_files -= white_list 85 | # print('old', old_files) 86 | # 逻辑应该是, 5min无变化就是旧的文件了 87 | 88 | if not old_files: 89 | pass 90 | else: 91 | convert(old_files) # 这里写的是需要处理的,处理完会删除 92 | # old_files = now_files 93 | 94 | time.sleep(5) 95 | # break 96 | -------------------------------------------------------------------------------- /LiveRecorder/videos/wait_upload/delete.sh: -------------------------------------------------------------------------------- 1 | function check() { 2 | 3 | echo "" 4 | #idir="/data/part1/wait_upload/" 5 | dir=`pwd` 6 | dir="/data/part1/BiliTools/LiveRecorder/videos/wait_upload" 7 | cd $dir 8 | echo "未转码的文件:" 9 | ls ../*.flv -aslh 10 | 11 | #echo "当前目录:" 12 | #pwd 13 | echo "等待上传:" 14 | ls *.flv -aslh 15 | echo "远程文件:" 16 | bypy list 17 | echo "--------" 18 | a=`bypy list | grep '.flv' | awk '{print $2":"$3}'` 19 | for line in $a 20 | do 21 | filename=`echo $line | cut -d ":" -f1` 22 | if [ ! -f $filename ]; then 23 | echo "$filename 本地已被删除!" 24 | continue 25 | fi 26 | remote_size=`echo $line | cut -d ":" -f2` 27 | local_size=`ls -l $filename | awk '{print $5}'` 28 | #echo $filename": local "$local_size", remote "$remote_size 29 | if [ $local_size = $remote_size ] && [ ${remote_size} -ne 0 ] ; then 30 | echo "rm -f $filename 删除! $local_size=$remote_size" 31 | rm -f $filename 32 | fi 33 | done 34 | echo '-------' 35 | echo "确认时间:" 36 | date 37 | echo '----done-----' 38 | } 39 | 40 | 41 | while true 42 | do 43 | check 44 | sleep 60 45 | done -------------------------------------------------------------------------------- /LiveRecorder/videos/wait_upload/upload.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | 4 | while true 5 | do 6 | bypy upload -v 7 | done -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BiliTools 2 | b站一些零散的脚本 3 | 4 | 5 | ## LiveRecorder 直播录屏姬 6 | 7 | **录屏视频使用请先征得up同意!** 8 | 9 | #### liverevorder.sh 10 | 脚本`liverevorder.sh`,输入房间号(**长号**)后启动,挂在服务器上即可 11 | 12 | 每当开播会自动录屏,未开播会报错,通过while循环等待up开播 13 | 14 | 在CentOS7+you-get上测试成功,理论上只要有you-get就可以实现功能 15 | 16 | #### 进度条修复 17 | 18 | 19 | 脚本 `video_fix.py` 需要`yamdi`、`ffmpeg`、`python3+` 20 | 21 | 此脚本用来修复录屏的进度条,但yamdi(在windows上叫做flvmdi)有时会修复失败,ffmpeg在mac上成功率很高 22 | 23 | **注意** 修复完成后的flv文件为添加后缀下划线的文件,存放在`wait_upload/`,如果修复失败,会直接把添加wrong后缀的源文件移动到wait_upload,无论如何,源文件都会消失 24 | 25 | **注意** 当`roomid/`目录下出现新flv文件时,才会去转换之前的文件,防止边下载边转换 26 | 27 | 28 | 参考 [http://blog.lc4t.me/2018/08/20/下载flv推流时异常修复/](http://blog.lc4t.me/2018/08/20/下载flv推流时异常修复/) 29 | 30 | #### 自动上传 31 | 32 | `upload.sh`,因为yamdi是分段生成文件的,可能出现未转换完就开始上传的情况,因此必须持续运行bypy 33 | 34 | bypy参考 [https://github.com/houtianze/bypy](https://github.com/houtianze/bypy) 35 | -------------------------------------------------------------------------------- /VideoDownloader/download.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | 4 | from loguru import logger 5 | 6 | file_path, _ = os.path.split(os.path.realpath(__file__)) 7 | logger.debug(f'文件所在目录为: {file_path}') 8 | 9 | parser = argparse.ArgumentParser() 10 | 11 | parser.add_argument('uid', help='作者UID') 12 | parser.add_argument('video_id', help='视频ID') 13 | parser.add_argument('--folder', help='指定文件夹,不指定则使用UID') 14 | parser.add_argument('--cookie', help='指定cookie文件') 15 | args = parser.parse_args() 16 | url = f'https://www.bilibili.com/video/{args.video_id}' 17 | 18 | params_cookie = '' 19 | if args.cookie: 20 | params_cookie = f'-c {args.cookie}' 21 | 22 | params_folder = f'-o {args.uid}' 23 | if args.folder: 24 | params_folder = f'-o "{args.folder}"' 25 | 26 | 27 | command = f'you-get {params_cookie} {url} {params_folder} --playlist' 28 | 29 | logger.info(command) 30 | --------------------------------------------------------------------------------