Skip to content
This repository has been archived by the owner on Oct 4, 2022. It is now read-only.

Commit

Permalink
第一次上传
Browse files Browse the repository at this point in the history
  • Loading branch information
xhlove committed Jan 4, 2020
1 parent 87074df commit 9e93912
Show file tree
Hide file tree
Showing 11 changed files with 800 additions and 0 deletions.
135 changes: 135 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# 额外
.vscode/
releases/
*.ass
methods/calc_danmu_pos.py

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/
61 changes: 61 additions & 0 deletions GetDanMu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python
# coding=utf-8
'''
# 作者: weimo
# 创建日期: 2020-01-04 12:59:11
# 上次编辑时间 : 2020-01-04 17:41:34
# 一个人的命运啊,当然要靠自我奋斗,但是...
'''

import sys

from argparse import ArgumentParser

from sites.qq import main as qq
from sites.iqiyi import main as iqiyi
from basic.ass import get_ass_head, check_font
from pfunc.dump_to_ass import write_lines_to_file
from methods.assbase import ASS
from methods.sameheight import SameHeight

# -------------------------------------------
# 基本流程
# 1. 根据传入参数确定网站,否则请求输入有关参数或链接。并初始化字幕的基本信息。
# 2. 解析链接得到相关视频/弹幕的参数,以及时长等
# 3. 根据网站对应接口获取全部弹幕
# 4. 转换弹幕
# 5. 写入字幕文件
# -------------------------------------------


def main():
parser = ArgumentParser(description="视频网站弹幕转换/下载工具,任何问题请联系[email protected]")
parser.add_argument("-f", "--font", default="微软雅黑", help="指定输出字幕字体")
parser.add_argument("-fs", "--font-size", default=28, help="指定输出字幕字体大小")
parser.add_argument("-s", "--site", default="qq", help="指定网站")
parser.add_argument("-cid", "--cid", default="", help="下载cid对应视频的弹幕(腾讯视频合集)")
parser.add_argument("-vid", "--vid", default="", help="下载vid对应视频的弹幕,支持同时多个vid,需要用逗号隔开")
parser.add_argument("-aid", "--aid", default="", help="下载aid对应视频的弹幕(爱奇艺合集)")
parser.add_argument("-tvid", "--tvid", default="", help="下载tvid对应视频的弹幕,支持同时多个tvid,需要用逗号隔开")
parser.add_argument("-u", "--url", default="", help="下载视频链接所指向视频的弹幕")
parser.add_argument("-y", "--y", action="store_true", help="覆盖原有弹幕而不提示")
args = parser.parse_args()
print(args.__dict__)
font_path, font_style_name = check_font(args.font)
ass_head = get_ass_head(font_style_name, args.font_size)
if args.site == "qq":
subtitles = qq(args)
if args.site == "iqiyi":
subtitles = iqiyi(args)

for file_path, comments in subtitles.items():
get_xy_obj = SameHeight("那就写这一句作为初始化测试吧!", font_path=font_path, font_size=args.font_size)
subtitle = ASS(file_path, get_xy_obj, font=font_style_name)
for comment in comments:
subtitle.create_new_line(comment)
write_lines_to_file(ass_head, subtitle.lines, file_path)

if __name__ == "__main__":
# 打包 --> pyinstaller -F .\qq.py -c -n GetDanMu_qq_1.1
main()
# subtitle = ASS()
Empty file added __init__.py
Empty file.
71 changes: 71 additions & 0 deletions basic/ass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env python
# coding=utf-8
'''
# 作者: weimo
# 创建日期: 2020-01-04 13:05:23
# 上次编辑时间 : 2020-01-04 15:52:11
# 一个人的命运啊,当然要靠自我奋斗,但是...
'''

import os

from basic.vars import fonts


ass_script = """[Script Info]
; Script generated by N
ScriptType: v4.00+
PlayResX: 1920
PlayResY: 1080
Aspect Ratio: 1920:1080
Collisions: Normal
WrapStyle: 0
ScaledBorderAndShadow: yes
YCbCr Matrix: TV.601"""

ass_style_head = """[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding"""
ass_style_default = """Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1"""
ass_style_base = """Style:{font},{font},{font_size},&H00FFFFFF,&H66FFFFFF,&H66000000,&H66000000,0,0,0,0,100,100,0.00,0.00,1,1,0,7,0,0,0,0"""
ass_events_head = """[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text"""
# 基于当前时间范围,在0~1000ms之间停留在(676.571,506.629)处,在1000~3000ms内从位置1300,600移动到360,600(原点在左上)
# ass_baseline = """Dialogue: 0,0:20:08.00,0:20:28.00,Default,,0,0,0,,{\t(1000,3000,\move(1300,600,360,600))\pos(676.571,506.629)}这是字幕内容示意"""

def get_ass_head(font_style_name, font_size):
ass_head = ass_script + "\n\n" + ass_style_head + "\n" + ass_style_base.format(font=font_style_name, font_size=font_size) + "\n\n" + ass_events_head
return ass_head

def check_font(font):
win_font_path = r"C:\Windows\Fonts"
maybe_font_path = os.path.join(win_font_path, font)
font_style_name = "微软雅黑"
font_path = os.path.join(win_font_path, fonts[font_style_name]) # 默认
if os.path.exists(font):
# 字体就在当前文件夹 或 完整路径
if os.path.isfile(font):
if os.path.isabs(font):
font_path = font
else:
font_path = os.path.join(os.getcwd(), font)
font_style_name = font[:-os.path.splitext(font)[-1].__len__()]
else:
pass
elif os.path.exists(maybe_font_path):
# 给的是字体文件名
if os.path.isfile(maybe_font_path):
font_path = maybe_font_path
font_style_name = font[:-os.path.splitext(font)[-1].__len__()]
else:
pass
elif fonts.get(font):
# 别名映射
font_path = os.path.join(win_font_path, fonts.get(font))
font_style_name = font
else:
pass
return font_path, font_style_name

def check_content(content: str, comments: list):
content = content.replace(" ", "")
if content in comments:
return
return content
19 changes: 19 additions & 0 deletions basic/vars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env python
# coding=utf-8
'''
# 作者: weimo
# 创建日期: 2020-01-04 13:16:18
# 上次编辑时间 : 2020-01-04 16:08:34
# 一个人的命运啊,当然要靠自我奋斗,但是...
'''
qqlive = {
"User-Agent":"qqlive"
}
iqiyiplayer = {
"User-Agent":"Qiyi List Client PC 7.2.102.1343"
}
fonts = {
"微软雅黑":"msyh.ttc",
"微软雅黑粗体":"msyhbd.ttc",
"微软雅黑细体":"msyhl.ttc",
}
68 changes: 68 additions & 0 deletions methods/assbase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python
# coding=utf-8
'''
# 作者: weimo
# 创建日期: 2020-01-04 13:01:04
# 上次编辑时间 : 2020-01-04 15:42:02
# 一个人的命运啊,当然要靠自我奋斗,但是...
'''

from datetime import datetime
from random import randint, choice

class ASS(object):

def __init__(self, file_path, get_xy_obj, font="微软雅黑"):
self.font = font
self.get_xy_obj = get_xy_obj

# 起点位置可以随机在一个区域出现
# 起点位置可以随机在一个区域出现 其他扩展
self.baseline = """Dialogue: 0,{start_time},{end_time},{font},,0,0,0,,{{{move_text}{color}}}{text}"""
self.lines = []

def create_new_line(self, comment):
text, color, timepoint = comment
start_time, end_time, show_time = self.set_start_end_time(timepoint)
font = self.set_random_font(line="")
move_text = self.set_start_end_pos(text, show_time)
color = self.set_color(color)
line = self.baseline.format(start_time=start_time, end_time=end_time, font=font, move_text=move_text, color=color, text=text)
self.lines.append(line)

def set_color(self, color: list):
# \1c&FDA742&
if color.__len__() == 1:
color = "\\1c&{}&".format(color[0].lstrip("#").upper())
else:
color = "\\1c&{}&".format(choice(color).lstrip("#").upper())
# color = "\\1c&{}&\\t(0,10000,\\2c&{}&".format(color[0].lstrip("#").upper(), color[1].lstrip("#").upper())
return color

def set_start_end_pos(self, text, show_time):
# 考虑不同大小字体下的情况 TODO
# \move(1920,600,360,600)
# min_index = self.get_min_length_used_y()
start_x = 1920
width, height, start_y = self.get_xy_obj.get_xy(text, show_time)
# start_y = self.all_start_y[min_index]
end_x = -(width + randint(0, 30))
end_y = start_y
move_text = "\\move({},{},{},{})".format(start_x, start_y, end_x, end_y)
# self.update_length_used_y(min_index, text.__len__() * 2)
return move_text

def set_start_end_time(self, timepoint):
# 40*60*60 fromtimestamp接收的数太小就会出问题
t = 144000
# 记录显示时间 用于计算字幕运动速度 在某刻的位置 最终决定弹幕分布选择
show_time = 15 #randint(10, 20)
st = t + timepoint
et = t + timepoint + show_time
start_time = datetime.fromtimestamp(st).strftime("%H:%M:%S.%f")[1:][:-4]
end_time = datetime.fromtimestamp(et).strftime("%H:%M:%S.%f")[1:][:-4]
return start_time, end_time, show_time

def set_random_font(self, line=""):
font = self.font
return font
Loading

0 comments on commit 9e93912

Please sign in to comment.