Skip to content

Instantly share code, notes, and snippets.

@Muratam
Created December 14, 2016 10:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Muratam/3f099faa7148ebd3647a1826990af8ac to your computer and use it in GitHub Desktop.
Save Muratam/3f099faa7148ebd3647a1826990af8ac to your computer and use it in GitHub Desktop.
gochiusa_sokuho.py
import twitter72
import requests
import re
import pickle
from urllib.parse import parse_qs
from pprint import pprint
from moviepy.editor import *
import random
import sys
import os
import json
import base64
import datetime
# 30s
def login(mail_tel, password):
s = requests.session()
s.post('https://account.nicovideo.jp/api/v1/login?site=niconico', params={
'mail_tel': mail_tel,
'password': password,
})
return s
def analyze_mp4(filename,out_filename,comments,ok_time=3100):
comments.sort(key=lambda x: x[1])
max_time = ok_time / 100.0
video = VideoFileClip(filename).subclip(0, max_time)
rangeses = [[], [], []]
def make_textclip(text, t, mail):
def check_dict(mail, dic, default):
for k, v in dic.items():
if k in mail:
return v
return default
# dicts
sizes = {"small": 15, "medium": 24, "big": 36}
colors = {
"white": "#FFFFFF", "red": "#FF0000", "pink": "#FF8080", "orange": "#FFC000",
"yellow": "#FFFF00", "green": "#00FF00", "cyan": "#00FFFF", "blue": "#0000FF",
"purple": "#C000FF", "black": "#000000",
"white2": "#CCCC99", "red2": "#CC0033", "pink2": "#FF33CC", "orange2": "#FF6600",
"yellow2": "#999900", "green2": "#00CC66", "cyan2": "#00CCCC", "blue2": "#3399FF",
"purple2": "#6633CC", "black2": "#666666",
}
poses = {"naka": 0, "ue": 1, "shita": 2}
# set parameter
color = check_dict(mail, colors, "#FFFFFF")
size = check_dict(mail, sizes, 24)
if size * len(text) > video.w:
size = int(video.w / len(text))
pos = check_dict(mail, poses, 0)
is_shita = pos == 2
t = t - 1 if pos == 0 else t
endtime = min(4, max_time - t)
textclip = (TextClip(text, font='./hiragino.ttc', fontsize=size,
color=color,
stroke_color="#000000",
stroke_width=0.5,
temptxt = text,
tempfilename = "aatxt.png"
)
.set_start(t)
.subclip(0, endtime))
# search y
m_begin = max(0, t)
m_end = min(t + endtime, max_time)
margin = 4
y_max = video.h - size - margin
y = 0 if not is_shita else y_max
for r_begin, r_end, t_begin, t_end in rangeses[pos]:
if t_begin <= m_end and m_begin <= t_end:
y = r_end if not is_shita else r_begin - size - margin * 2
y += margin
if y > y_max or y < 0:
y = random.randrange(0,y_max)
y = max(0,min(y,y_max))
m_range = [y, y + size,m_begin, m_end]
rangeses[pos].append(m_range)
# set position
if pos == 0:
begin_x = video.w
end_x = -size * len(text)
textclip = textclip.set_pos(
lambda t: (begin_x + (end_x - begin_x) * (t / endtime), y))
else:
textclip = textclip.set_pos(("center", y))
return textclip
txt_clips = []
for text, t, date, mail in comments:
clip = make_textclip(text, t / 100.0, mail)
txt_clips.append(clip)
result = CompositeVideoClip([video] + txt_clips)
result.write_videofile(out_filename + ".mp4", fps=30, audio=True)
result.save_frame(out_filename + ".png",2)
def get_comments(thread_id, s, ok_time=3100, version="20090904"):
movie_info = s.post(
"http://flapi.nicovideo.jp/api/getflv/{thread_id}".format(thread_id=thread_id))
qs = parse_qs(movie_info.text)
ms, user_id, userkey = qs["ms"][0], qs["user_id"][0], qs["userkey"][0]
optional_thread_id = qs["optional_thread_id"][0]
thread_info = s.get(
"http://flapi.nicovideo.jp/api/getthreadkey?language_id=0&thread={thread_id}".format(thread_id=thread_id))
found = re.findall(r'threadkey=(.+)&force_184=(.+)', thread_info.text)
threadkey, force_184 = found[0]
xml = """
<packet>
<thread thread="{thread}" version="{version}" user_id="{user_id}"
threadkey="{threadkey}" force_184="{force_184}" scocomments="1" with_global="1" />
<thread_leaves thread="{thread}" user_id="{user_id}"
threadkey="{threadkey}" force_184="{force_184}" scocomments="1" >0-24:100,1000</thread_leaves>
</packet>""".format(
version=version, thread=thread_id, opt_thread=optional_thread_id,
user_id=user_id, threadkey=threadkey, force_184=force_184)
comments = requests.post("http://nmsg.nicovideo.jp/api/", data=xml)
founds = re.findall(r'<chat (.+?)>(.+?)</chat>',
comments.content.decode("utf-8"))
comments = []
for info, found in founds:
found = found.replace("\u3000", " ")
# vpos,date,mail
vpos = int(re.findall(r'vpos="(\d+)"', info)[0])
date = int(re.findall(r'date="(\d+)"', info)[0])
mail = re.findall(r'mail="(.+?)"', info)
mail = mail[0] if mail else ""
if len(found) > 30 or len(found) < 4 or vpos > ok_time:
continue
comments.append([found, vpos, date, mail])
comments.sort(key=lambda x: x[1])
return comments
def check_update_comments(thread_id, comments):
comments = [_ for _ in comments if "big" in _[3] ]
filename = "niconico_" + str(thread_id) + ".pickle"
with open(filename, mode="ab") as f:
pass
with open(filename, mode="rb") as f:
try:
pre_data = pickle.Unpickler(f).load()
except:
pre_data = []
with open(filename, mode="wb") as f:
pickle.dump([_[2] for _ in comments], f)
res = [_[0] for _ in comments if _[2] not in pre_data]
return res
def main(args):
thread_id = "1397552685"
with open("gochiusa_token") as f:
mail_tel, password, c_key, c_secret, a_key, a_secret = f.read().split("\n")
s = login(mail_tel, password)
if ("mp4" in args ) or ("png" in args):
ok_time = 3100
comments = get_comments(thread_id, s, ok_time)
analyze_mp4("gochiusa.mp4","gochiusa_with_comment",comments,ok_time)
extention = "mp4" if "mp4" in args else "png"
text = datetime.datetime.now().strftime("%m月%d日%H時現在のごちうさ速報です")
res = twitter72.tweet(c_key, c_secret, a_key, a_secret, text,"gochiusa_with_comment." + extention)
return res if res else ""
else:
ok_time = 500
comments = get_comments(thread_id, s, ok_time)
gochis = check_update_comments(thread_id, comments)
for gochi in gochis:
twitter72.tweet(c_key, c_secret, a_key, a_secret, gochi)
twitter72.fav_word(c_key, c_secret, a_key, a_secret,'"ごちうさ速報" OR "ごちうさニュース速報" -@gochiusa_sokuho')
if __name__ == "__main__":
main(sys.argv)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment