Skip to content

Commit

Permalink
cui新增下載下載指定劇集, -e 開啓
Browse files Browse the repository at this point in the history
單任務或單綫程顯示實時文件體積
Ctrl+C 可以終止多綫程下載, 友好推出提示
處理anime表不存在異常
update readme
  • Loading branch information
miyouzi committed Jan 10, 2019
1 parent 6026377 commit e4da4eb
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 60 deletions.
14 changes: 14 additions & 0 deletions .idea/dataSources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 36 additions & 7 deletions Anime.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import Config
from bs4 import BeautifulSoup
import re, time, os, platform, subprocess, requests, random, sys
from Color import err_print
from ColorPrint import err_print
import threading


Expand All @@ -32,13 +32,15 @@ def __init__(self, sn):
self._m3u8_dict = {}
self.video_resolution = 0
self.video_size = 0
self.realtime_show_file_size = False

self.__init_header() # http header
self.__get_src() # 获取网页, 产生 self._src (BeautifulSoup)
self.__get_title() # 提取页面标题
self.__get_bangumi_name() # 提取本番名字
self.__get_episode() # 提取剧集码,str
self.__get_episode_list() # 提取剧集列表,结构 {'episode': sn},储存到 self._episode_list, sn 为 int
# 提取剧集列表,结构 {'episode': sn},储存到 self._episode_list, sn 为 int, 考慮到 劇場版 sp 等存在, key 為 str
self.__get_episode_list()

def renew(self):
self.__get_src()
Expand Down Expand Up @@ -145,7 +147,8 @@ def __request(self, req, no_cookies=False):
self._cookies['nologinuser'] = f.cookies.get_dict()['nologinuser']
return f

def download(self, resolution='', save_dir=''):
def download(self, resolution='', save_dir='', realtime_show_file_size=False):
self.realtime_show_file_size = realtime_show_file_size
if not resolution:
resolution = self._settings['download_resolution']

Expand Down Expand Up @@ -285,16 +288,36 @@ def download_video(resolution):
if os.path.exists(downloading_file):
os.remove(downloading_file) # 清理任务失败的尸体

print('正在下載: sn=' + str(self._sn) + ' ' + filename)
# subprocess.call(ffmpeg_cmd, creationflags=0x08000000) # 仅windows
run_ffmpeg = subprocess.Popen(ffmpeg_cmd, stdout=subprocess.PIPE, bufsize=204800, stderr=subprocess.PIPE)

def check_ffmpeg_alive():
# 应对ffmpeg卡死, 资源限速等,若 1min 中内文件大小没有增加超过 3M, 则判定卡死
if self.realtime_show_file_size: # 是否实时显示文件大小, 设计仅 cui 下载单个文件或线程数=1时适用
sys.stdout.write('正在下載: sn=' + str(self._sn) + ' ' + filename)
sys.stdout.flush()
else:
print('正在下載: sn=' + str(self._sn) + ' ' + filename)

time.sleep(2)
time_counter = 1
pre_temp_file_size = 0
while run_ffmpeg.poll() is None:

if self.realtime_show_file_size:
# 实时显示文件大小
if os.path.exists(downloading_file):
size = os.path.getsize(downloading_file)
size = size / float(1024*1024)
size = round(size, 2)
sys.stdout.write('\r')
sys.stdout.write('正在下載: sn=' + str(self._sn) + ' ' + filename + ' ' + str(size) + 'MB ')
sys.stdout.flush()
else:
sys.stdout.write('\r')
sys.stdout.write('正在下載: sn=' + str(self._sn) + ' ' + filename + ' 文件尚未生成 ')
sys.stdout.flush()

if time_counter % 60 == 0 and os.path.exists(downloading_file):
temp_file_size = os.path.getsize(downloading_file)
a = temp_file_size - pre_temp_file_size
Expand All @@ -308,9 +331,15 @@ def check_ffmpeg_alive():
time_counter = time_counter + 1

ffmpeg_checker = threading.Thread(target=check_ffmpeg_alive) # 检查线程
ffmpeg_checker.setDaemon(True) # 如果 Anime 线程被 kill, 检查进程也应该结束
ffmpeg_checker.start()
run = run_ffmpeg.communicate()
return_str = str(run[1])

if self.realtime_show_file_size:
sys.stdout.write('\n')
sys.stdout.flush()

if run_ffmpeg.returncode == 0 and (return_str.find('Failed to open segment') < 0):
# 执行成功 (ffmpeg正常结束, 每个分段都成功下载)
if os.path.exists(output_file):
Expand All @@ -319,8 +348,8 @@ def check_ffmpeg_alive():
self.video_size = int(os.path.getsize(output_file) / float(1024 * 1024)) # 记录文件大小,单位为 MB
print('下載完成: sn=' + str(self._sn) + ' ' + filename)
else:
self.video_size = 0
err_print('下載失败! sn=' + str(self._sn) + ' ' + filename + ' ffmpeg_return_code=' + str(run_ffmpeg.returncode) + ' Bad segment=' + str(return_str.find('Failed to open segment')))
err_print('下載失败! sn=' + str(self._sn) + ' ' + filename + ' ffmpeg_return_code=' + str(
run_ffmpeg.returncode) + ' Bad segment=' + str(return_str.find('Failed to open segment')))

get_device_id()
gain_access()
Expand All @@ -335,4 +364,4 @@ def check_ffmpeg_alive():
check_no_ad()
get_playlist()
parse_playlist()
download_video(resolution)
download_video(resolution)
File renamed without changes.
2 changes: 1 addition & 1 deletion Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
config_path = os.path.join(working_dir, 'config.json')
sn_list_path = os.path.join(working_dir, 'sn_list.txt')
cookies_path = os.path.join(working_dir, 'cookies.txt')
aniGamerPlus_version = 'v4.0'
aniGamerPlus_version = 'v5.0'
latest_config_version = 1.1


Expand Down
65 changes: 54 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# aniGamerPlus
巴哈姆特動畫瘋自動下載工具

windows 用戶可以[**點擊這裡**](https://github.com/miyouzi/aniGamerPlus/releases/tag/v4.0)下載exe文件使用.
windows 用戶可以[**點擊這裡**](https://github.com/miyouzi/aniGamerPlus/releases/tag/v5.0)下載exe文件使用.

ffmpeg 需要另外下載, [**點擊這裡前往下載頁**](https://ffmpeg.zeranoe.com/builds/). 若不知道如何將 ffmpeg 放入 PATH 則直接將 **ffmpeg.exe** 放在和本程式同一個文件夾下即可.

Expand Down Expand Up @@ -66,7 +66,7 @@ pip3 install requests beautifulsoup4 lxml termcolor

用戶cookie文件, 將瀏覽器的cookie字段複製, 已**cookies.txt**為文件名保存在程序目錄下即可

:warning: **登陸時請勾選"保持登入狀態", 并且不更換瀏覽器登陸, 否則cookie將可能被刷新**
:warning: **登陸時請勾選"保持登入狀態", 并且不更換瀏覽器登陸, 不異地登陸, 否則cookie將可能被刷新**

### sn_list.txt

Expand Down Expand Up @@ -105,26 +105,69 @@ sqlite3資料庫, 可以使用 [SQLite Expert](http://www.sqliteexpert.com/) 等
參數:
```
>python3 aniGamerPlus.py -h
當前aniGamerPlus版本: v5.0
usage: aniGamerPlus.py [-h] --sn SN [--resolution {360,480,540,720,1080}]
[--download_mode {single,latest,all}]
[--thread_limit THREAD_LIMIT]
[--download_mode {single,latest,all,range}]
[--thread_limit THREAD_LIMIT] [--current_path]
[--episodes EPISODES]
optional arguments:
-h, --help show this help message and exit
--sn SN, -s SN 視頻sn碼(數字)
--resolution {360,480,540,720,1080}, -r {360,480,540,720,1080}
指定下載清晰度(數字)
--download_mode {single,latest,all}, -m {single,latest,all}
--download_mode {single,latest,all,range}, -m {single,latest,all,range}
下載模式
--thread_limit THREAD_LIMIT, -t THREAD_LIMIT
最高并發下載數(數字)
>python3 aniGamerPlus.py -s SN -r RESOLUTION -m DOWNLOAD_MODE -t THREAD_LIMIT
--current_path, -c 下載到當前工作目錄
--episodes EPISODES, -e EPISODES
僅下載指定劇集
```

**-s** 接要下載視頻的sn碼,不可空
- **-s** 接要下載視頻的sn碼,不可空

**-r** 接要下載的清晰度, 可空, 空則讀取**config.json**中的定義, 不存在則選取最近可用清晰度
- **-r** 接要下載的清晰度, 可空, 空則讀取**config.json**中的定義, 不存在則選取最近可用清晰度

**-m** 接下載模式, 可空, 空則下載傳入sn碼的視頻, 另有 **all** 下載此番劇所有劇集 和 **latest** 下載此番劇最新一集可選

**-t** 接最大并發下載數, 可空, 空則讀取**config.json**中的定義
- **-m** 接下載模式, 可空, 空則下載傳入sn碼的視頻

- **single** 下載此 sn 單集(默認)

- **all** 下載此番劇所有劇集

- **latest** 下載此番劇最新一集

- **range** 下載此番指定的劇集

- **-t** 接最大并發下載數, 可空, 空則讀取**config.json**中的定義

- **-e** 下載此番劇指定劇集, 支持範圍輸入, 支持多個不連續聚集下載, 僅支持數字命名的劇集

- -e 參數優先于 -m 參數, 使用 -e 參數時, 强制為 range 模式

- 若使用 -m range 則必須使用 -e 指定需要下載的劇集

- 若指定了不存在的劇集會警告並跳過, 僅下載存在的劇集

- 指定不連續劇集請用英文逗號","分隔, 中間無空格

- 指定連續劇集格式: 起始劇集-終止劇集. 舉例想下載第5到9集, 則格式為 5-9

- 將會按劇集順序下載

- 舉例:

- 想下載第1,2,3集
```python3 aniGamerPlus.py -s 10218 -e 1,2,3```

- 想下載第5到8集
```python3 aniGamerPlus.py -s 10218 -e 5-8```

- 想下載第2集, 第5到8集, 第12集
```python3 aniGamerPlus.py -s 10218 -e 2,5-8,12```

- 截圖:

![](screenshot/cui_range_mode.png)

![](screenshot/cui_range_mode_err.png)
Loading

0 comments on commit e4da4eb

Please sign in to comment.