UPDATE

上级 df352508
https://live.douyin.com/40461216038
\ No newline at end of file
import os
import sys
os.execv(sys.executable, ['python'] + sys.argv)
\ No newline at end of file
[1]
循环时间(秒) = 60
直播保存路径 =
视频保存格式ts|flv|mp4|mp3 = TS
是否显示直播地址 =
是否显示循环秒数 =
mp4格式是否转码h264 =
本地代理端口 =
ts格式分段录制是否开启 =
视频分段大小(兆) = 1000
ts录制完成后自动增加生成mp4格式 =
2023-04-14 14:26:34,719 - ------------------------------------------------------
print('欢迎来到 InsCode')
\ No newline at end of file
print('欢迎来到 InsCode'python
\ No newline at end of file
#-*- coding: utf-8 -*-
import random
import requests
import re
import os
import urllib.request
import urllib.parse
import sys
from bs4 import BeautifulSoup
import time
import json
import configparser
import subprocess
import logging
import threading
import string
import jsonpath
version=221008 #请注意把下面这个地方和文件名改了就行啦
#pyinstaller -F 抖音直播录制_221008.py
class Logger(object):
def __init__(self, stream=sys.stdout):
output_dir = "log"
if not os.path.exists(output_dir):
os.makedirs(output_dir)
log_name = "崩溃记录日志.log"
filename = os.path.join(output_dir, log_name)
self.terminal = stream
self.log = open(filename, 'w',encoding="utf-8-sig")
def write(self, message):
self.terminal.write(message)
self.log.write(message)
def flush(self):
pass
sys.stdout = Logger(sys.stdout) # 将输出记录到log
sys.stderr = Logger(sys.stderr) # 将错误信息记录到log
# 创建一个logger
logger = logging.getLogger('抖音直播录制%s版'%str(version))
logger.setLevel(logging.INFO)
# 创建一个handler,用于写入日志文件
if not os.path.exists("log"):
os.makedirs("log")
fh = logging.FileHandler("log/直播日志文件.log",encoding="utf-8-sig",mode="a")
fh.setLevel(logging.WARNING)
# 再创建一个handler,用于输出到控制台
# ch = logging.StreamHandler()
# ch.setLevel(logging.INFO)
# formatter = logging.Formatter()
# ch.setFormatter(formatter)
# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(message)s')
fh.setFormatter(formatter)
#ch.setFormatter(formatter)
# 给logger添加handler
logger.addHandler(fh)
# logger.addHandler(ch)
# socket.setdefaulttimeout(10)
recording=set()
unrecording=set()
logger.warning("------------------------------------------------------") #分割线
def updateFile(file,old_str,new_str):
file_data = ""
with open(file, "r", encoding="utf-8-sig") as f:
for line in f:
if old_str in line:
line = line.replace(old_str,new_str)
file_data += line
with open(file,"w",encoding="utf-8-sig") as f:
f.write(file_data)
def get_xx():
string.ascii_letters= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
return random.choice(string.ascii_lowercase)
def get_dx():
string.ascii_letters= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
return random.choice(string.ascii_uppercase)
def subwords(words):
words=re.sub('[-? * : " < > / | .]', '', words)
words=re.sub(r'\\', '', words)
return words
def convertsmp4(address):
if tsconvertmp4:
_output = subprocess.check_output([
"ffmpeg", "-i",address,
"-c:v","copy",
"-f","mp4",address+".mp4",
], stderr = subprocess.STDOUT)
#print("转换到mp4")
def get_roomid(html):
'''
js = re.findall(r"<script>(.{666,}?)</script>", html)[0]
ret = json.loads(js.replace("window.__INIT_PROPS__ = ",""))
return ret["/webcast/reflow/:id"]["room"]["owner"]["own_room"]["room_ids_str"][0]
'''
ret =json.loads(html)
return ret["data"]["room"]["owner"]["own_room"]["room_ids_str"][0]
def get_status(html):
js = re.findall(r"<script>(.{666,}?)</script>", html)[0]
ret = json.loads(js.replace("window.__INIT_PROPS__ = ",""))
return ret["/webcast/reflow/:id"]["room"]["status"]
def get_real_url(rid,startname,changestaute):
global recording
try:
#print('开始获取真实地址:')
Modelheaders = {
'User-Agent':'Mozilla/5.0 (Linux; U; Android 8.1.0; en-US; Nexus 6P Build/OPM7.181205.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.11.1.1197 Mobile Safari/537.36'
}
if len(proxies2)>0:
res=requests.get(rid,headers=Modelheaders,proxies=proxies2,timeout=15)
else:
res=requests.get(rid,headers=Modelheaders,timeout=15)
roomid = ((res.url).split('/')[-1]).split('?')[0]
# jsurl = "https://webcast.amemv.com/webcast/room/reflow/info/?type_id=0&live_id=1&room_id=" + roomid + "&app_id=1128"
jsurl = "https://webcast.amemv.com/webcast/room/reflow/info/?verifyFp=verify_l7u0qa4v_lx77IkKY_kSHg_411A_9JqE_9h6LMXjaPvb" + get_dx() + "&type_id=0&live_id=1&room_id=" + roomid + "&sec_user_id=&app_id=1128&msToken=HZq7LCnGU_J6-_ZIP8z7ugoxa3TO4kiefFKCiLe139sbMkgLan0uEVijUk8B7aBNseUuwGfvGToHXv7VgGGI4ELJPWBedkZZdZtq9se_dK2gQ_dP-Rw" + get_xx() + "&X-Bogus=DFSzswVOye0ANHQbSKxn6VXAIQ5" + get_xx()
if len(proxies2) > 0:
resjs = requests.get(jsurl, headers=headers, proxies=proxies2, timeout=15)
else:
resjs = requests.get(jsurl, headers=headers, timeout=15)
#抖音状态码参考:
#room_status = str(get_status(res.text))
# print("直播间状态: "+room_status)
# if room_status=="2":
# pass
# if changestaute!=room_status:
# changestaute=room_status
# logger.warning("直播间正在直播")
# else:
# print("直播间正在直播")
# elif room_status=="4":
# pass
# if changestaute!=room_status:
# changestaute=room_status
# logger.warning("直播间直播已结束,正在等待下次开播")
# else:
# print("直播间直播已结束,正在等待下次开播")
# elif room_status=="1":
# pass
# if changestaute!=room_status:
# changestaute=room_status
# logger.warning("直播间未直播")
# else:
# print("直播间未直播")
# else:
# if changestaute!=room_status:
# changestaute=room_status
# logger.warning("未知状态.直播间状态返回码: "+room_status)
# else:
# print("未知状态.直播间状态返回码: "+room_status)
try:
room_ids_str = get_roomid(resjs.text)
changestautenow=True
except:
changestautenow=False
#nowdate=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
nowdate=time.strftime("%H:%M:%S", time.localtime())
if changestaute!=changestautenow:
changestaute=changestautenow
if changestautenow==True:
logger.warning(startname+" 正在直播中 ")
print("\r"+startname+" 正在直播 " + nowdate)
if startname in unrecording:
unrecording.add(startname)
else:
logger.warning(startname+" 直播间未直播,等待开播中.. ")
#print(startname+" 直播间未直播,等待开播中.. "+nowdate)
if startname in recording:
recording.remove(startname)
if startname not in unrecording:
unrecording.add(startname)
else:
if changestautenow==True:
print("\r"+startname+" 正在直播中 " +nowdate)
else:
#print(startname+" 直播间未直播,等待开播中.. "+nowdate)
if startname in recording:
recording.remove(startname)
if startname not in unrecording:
unrecording.add(startname)
#room_url = 'https://webcast.amemv.com/webcast/reflow/{}'.format(room_ids_str)+"?u_code=70baflkg&app=aweme&utm_campaign=client_share&utm_medium=ios&tt_from=copy&utm_source=copy"
# room_url = "https://webcast.amemv.com/webcast/room/reflow/info/?type_id=0&live_id=1&room_id=" + room_ids_str + "&app_id=1128"
room_url = "https://webcast.amemv.com/webcast/room/reflow/info/?verifyFp=verify_l7u0qa4v_lx77IkKY_kSHg_411A_9JqE_9h6LMXjaPvb" + get_dx() + "&type_id=0&live_id=1&room_id=" + room_ids_str + "&sec_user_id=&app_id=1128&msToken=HZq7LCnGU_J6-_ZIP8z7ugoxa3TO4kiefFKCiLe139sbMkgLan0uEVijUk8B7aBNseUuwGfvGToHXv7VgGGI4ELJPWBedkZZdZtq9se_dK2gQ_dP-Rw" + get_xx() + "&X-Bogus=DFSzswVOye0ANHQbSKxn6VXAIQ5" + get_xx()
Modelheaders = {
'User-Agent':'Mozilla/5.0 (Linux; U; Android 8.1.0; en-US; Nexus 6P Build/OPM7.181205.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.11.1.1197 Mobile Safari/537.36'
}
if len(proxies2)>0:
res=requests.get(room_url,headers=Modelheaders,proxies=proxies2,timeout=15)
else:
res=requests.get(room_url,headers=Modelheaders,timeout=15)
json_res = json.loads(res.text)
changestaute = jsonpath.jsonpath(json_res, '$.data.room.status')[0]
hls_pull_url = jsonpath.jsonpath(json_res, '$.data.room.stream_url.hls_pull_url_map')[0]
hls_pull_url2 = list(hls_pull_url.values())[0]
# print(hls_pull_url2)
real_url = [hls_pull_url2, changestaute]
return real_url
except Exception as _e:
real_url = [None,changestaute]
return real_url
headers = {
'User-Agent': 'Mozilla/5.0 (Linux; U; Android 8.1.0; en-US; Nexus 6P Build/OPM7.181205.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.11.1.1197 Mobile Safari/537.36'
}
print( '-------------- 吾爱破解论坛 程序当前配置----------------' )
print("循环值守录制抖音直播 版本:%s"%str(version))
try:
f =open("config.ini",'r', encoding='utf-8-sig')
f.close()
except IOError:
f = open("config.ini",'w', encoding='utf-8-sig')
f.close()
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
rid=config.get('1', '直播地址')
except:
rid=""
if os.path.isfile("URL_config.ini"):
f =open("URL_config.ini",'r', encoding='utf-8-sig')
inicontent=f.read()
f.close()
else:
inicontent=""
if len(inicontent)==0:
print('请输入要录制的抖音主播分享网址,例如: https://v.douyin.com/EQBYoH/:')
inurl=input()
f = open("URL_config.ini",'a+',encoding='utf-8-sig')
f.write(inurl)
f.close()
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', '直播地址')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
#config.set('1', '直播地址', inurl)# 给type分组设置值
config.set('1', '循环时间(秒)', '60')# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
delaydefault=config.getint('1', '循环时间(秒)')
except:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', '循环时间(秒)')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', '循环时间(秒)', '60')# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
delaydefault=4
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
videopath=config.get('1', '直播保存路径')
except:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', '直播保存路径')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', '直播保存路径', '')# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
videopath=""
if len(videopath)>0:
if not os.path.exists(videopath):
print("配置文件里,直播保存路径并不存在,请重新输入一个正确的路径.或留空表示当前目录,按回车退出")
input("程序结束")
os._exit(0)
else:
print("视频保存路径: "+videopath)
else:
print("视频保存路径: 当前目录")
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
videosavetype=config.get('1', '视频保存格式TS|FLV|MP4|MP3')
except Exception as _e:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', '视频保存格式TS|FLV|MP4|MP3')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', '视频保存格式TS|FLV|MP4|MP3',"TS")# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
videosavetype="TS"
#是否显示直播地址
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
videom3u8=config.get('1', '是否显示直播地址')
except Exception as _e:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', '是否显示直播地址')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', '是否显示直播地址',"否")# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
videom3u8="否"
if videom3u8=="是":
videom3u8=True
else:
videom3u8=False
#是否显示循环秒数
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
looptime=config.get('1', '是否显示循环秒数')
except Exception as _e:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', '是否显示循环秒数')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', '是否显示循环秒数',"否")# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
looptime="否"
if looptime=="是":
looptime=True
else:
looptime=False
#这里是控制MP4是否转码
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
videoencode=config.get('1', 'MP4格式是否转码H264')
except Exception as _e:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', 'MP4格式是否转码H264')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', 'MP4格式是否转码H264',"否")# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
videoencode="否"
if videoencode=="是":
videoencode=True
else:
videoencode=False
#这里是控制是否设置代理
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
proxies2=config.get('1', '本地代理端口')
proxiesn=proxies2
if len(proxies2)>0:
proxies2={'https': 'http://127.0.0.1:'+str(proxies2)}
print("检测到有设置代理地址为: "+'http://127.0.0.1:'+str(proxiesn))
except Exception as _e:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', '本地代理端口')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', '本地代理端口',"")# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
proxies2=""
#这里是控制TS是否分段
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
Splitvideobysize=config.get('1', 'TS格式分段录制是否开启')
except Exception as _e:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', 'TS格式分段录制是否开启')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', 'TS格式分段录制是否开启',"否")# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
Splitvideobysize="否"
if Splitvideobysize=="是":
Splitvideobysize=True
else:
Splitvideobysize=False
#这里是控制TS分段大小
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
Splitsize=config.getint('1', '视频分段大小(兆)')
except:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', '视频分段大小(兆)')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', '视频分段大小(兆)', '1000')# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
Splitsize=1000 #1g
#分段大小不能小于5m
if Splitsize<5:
Splitsize=5 #最低不能小于5m
Splitsizes=Splitsize*1024*1024 #分割视频大小,转换为字节
if Splitvideobysize:
print("TS录制分段开启,录制分段大小为 %d M"%Splitsize)
#这里是控制TS是否追加mp4格式
try:
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8-sig')
tsconvertmp4=config.get('1', 'TS录制完成后自动增加生成MP4格式')
except Exception as _e:
config = configparser.ConfigParser()
# -read读取ini文件
config.read('config.ini', encoding='utf-8-sig')
listx = []
listx = config.sections()# 获取到配置文件中所有分组名称
if '1' not in listx:# 如果分组type不存在则插入type分组
config.add_section('1')
else:
config.remove_option('1', 'TS录制完成后自动增加生成MP4格式')# 删除type分组的stuno
# config.remove_section('tpye')# 删除配置文件中type分组
config.set('1', 'TS录制完成后自动增加生成MP4格式',"否")# 给type分组设置值
o = open('config.ini', 'w',encoding='utf-8-sig')
config.write(o)
o.close()#不要忘记关闭
tsconvertmp4="否"
if tsconvertmp4=="是":
tsconvertmp4=True
else:
tsconvertmp4=False
if len(videosavetype)>0:
if videosavetype.upper()=="FLV":
videosavetype="FLV"
print("直播视频保存为FLV格式")
elif videosavetype.upper()=="TS":
videosavetype="TS"
print("直播视频保存为TS格式")
elif videosavetype.upper()=="MP4":
videosavetype="MP4"
print("直播视频保存为MP4格式")
elif videosavetype.upper()=="MP3":
videosavetype="MP3"
print("直播视频保存为MP3音频格式")
else:
videosavetype="TS"
print("直播视频保存格式设置有问题,这次录制重置为默认的TS格式")
else:
videosavetype="TS"
print("直播视频保存为TS格式")
if videoencode==True and videosavetype=="MP4":
print("转码设置:MP4实时转码H264")
if videoencode==False and videosavetype=="MP4":
print("转码设置:MP4不进行转码")
allLive=[] #全部的直播
allRecordingUrl=[]
print( '......................................................' )
def startgo(line):
global allLive
recordfinish=False
recordfinish_2=False
counttime=time.time()
global videopath
ridcontent = line.split(',')
rid=ridcontent[0]
if len(ridcontent)>1:
print("传入地址: "+ridcontent[0],ridcontent[1])
else:
print("传入地址: "+ridcontent[0])
while True:
try:
if len(proxies2)>0:
res=requests.get(rid,headers=headers,proxies=proxies2,timeout=15)
else:
res=requests.get(rid,headers=headers,timeout=15)
if res.status_code!=200:
print(res.status_code)
#input('直播地址连接失败,请手动检测配置文件里的地址是否正常')
print(rid+' 的直播地址连接失败,请手动检测配置文件里的地址是否正常')
else:
#print(res.current_url)
res.encoding='utf-8-sig'
roomid = ((res.url).split('/')[-1]).split('?')[0]
# jsurl = "https://webcast.amemv.com/webcast/room/reflow/info/?type_id=0&live_id=1&room_id=" + roomid + "&app_id=1128"
jsurl = "https://webcast.amemv.com/webcast/room/reflow/info/?verifyFp=verify_l7u0qa4v_lx77IkKY_kSHg_411A_9JqE_9h6LMXjaPvb" + get_dx() + "&type_id=0&live_id=1&room_id=" + roomid + "&sec_user_id=&app_id=1128&msToken=HZq7LCnGU_J6-_ZIP8z7ugoxa3TO4kiefFKCiLe139sbMkgLan0uEVijUk8B7aBNseUuwGfvGToHXv7VgGGI4ELJPWBedkZZdZtq9se_dK2gQ_dP-Rw" + get_xx() + "&X-Bogus=DFSzswVOye0ANHQbSKxn6VXAIQ5" + get_xx()
if len(proxies2) > 0:
resjs = requests.get(jsurl, headers=headers, proxies=proxies2, timeout=15)
else:
resjs = requests.get(jsurl, headers=headers, timeout=15)
# print(resjs.text)
if resjs.status_code != 200:
print(resjs.status_code)
print(jsurl + ' 的直播地址连接失败,请手动检测配置文件里的地址是否正常')
else:
resjs.encoding = 'utf-8-sig'
#print (resjs.text)
resjs=json.loads(resjs.text)
startname=resjs["data"]["room"]["owner"]['nickname']
startname = subwords(startname)
if startname in allLive:
print("新增的地址: %s 已经存在,本条线程将会退出"%startname)
namelist.append(str(rid)+"|"+str("#"+rid))
exit(0)
if len(ridcontent)==1:
namelist.append(str(ridcontent[0])+"|"+str(ridcontent[0]+",主播: "+startname.strip()))
break
except Exception as e:
print("错误信息644:"+str(e)+"\r\n读取的地址为: "+str(rid) +" 发生错误的行数: "+str(e.__traceback__.tb_lineno) )
print(rid+' 的直播地址连接失败,请检测这个地址是否正常,可以重启本程序--requests获取失败')
x=delaydefault
if recordfinish==True:
counttimeend=time.time()-counttime
if counttimeend<60:
x=2
else:
recordfinish=False
else:
x=delaydefault
while x:
x = x-1
if looptime:
print('\r循环等待%d秒 '%x ,end="")
time.sleep(1)
if looptime:
print('\r重新检测直播间中...',end="")
changestaute=""
while True:
real_urlcontent = get_real_url(rid,startname,changestaute)
real_url=real_urlcontent[0]
changestaute=real_urlcontent[1]
if real_url!=None:
now = time.strftime("%Y-%m-%d-%H-%M-%S",time.localtime(time.time()))
try:
if len(videopath)>0:
if videopath[-1]!="\\":
videopath=videopath+"\\"
if not os.path.exists(videopath+startname):
os.makedirs(videopath+startname)
else:
if not os.path.exists(startname):
os.makedirs('./'+startname)
except Exception as e:
print("路径错误信息708: "+str(e) +" 发生错误的行数: "+str(e.__traceback__.tb_lineno) )
if not os.path.exists(videopath+startname):
print("保存路径不存在,不能生成录制.请避免把本程序放在c盘,桌面,下载文件夹,qq默认传输目录.请重新检查设置")
videopath=""
print("因为配置文件的路径错误,本次录制在程序目录")
if videosavetype=="FLV":
filename=startname + '_' + now + '.flv'
if len(videopath)==0:
print("\r"+startname+" 录制视频中: "+os.getcwd()+"\\"+startname +'\\'+ filename)
else:
print("\r"+startname+" 录制视频中: "+videopath+startname +'\\'+ filename)
if not os.path.exists(videopath+startname):
print("目录均不能生成文件,不能生成录制.请避免把本程序放在c盘,桌面,下载文件夹,qq默认传输目录.请重新检查设置,程序将会退出")
input("请按回车退出")
os._exit(0)
#flv录制格式
try:
recording.add(startname)
_filepath, _ = urllib.request.urlretrieve(real_url, videopath+startname +'\\'+ filename)
recordfinish=True
recordfinish_2=True
counttime=time.time()
if startname in recording:
recording.remove(startname)
if startname in unrecording:
unrecording.add(startname)
except:
print('\r'+time.strftime('%Y-%m-%d %H:%M:%S ') +startname + ' 未开播')
elif videosavetype=="MP4":
filename=startname + '_' + now + ".mp4"
if len(videopath)==0:
print("\r"+startname+ " 录制视频中: "+os.getcwd()+"\\"+startname +'\\'+ filename)
else:
print("\r"+startname+ " 录制视频中: "+videopath+startname +'\\'+ filename)
ffmpeg_path = "ffmpeg"
file = videopath+startname +'\\'+ filename
try:
real_url=real_url.replace("\\u0026","&")
recording.add(startname)
if videoencode:
_output = subprocess.check_output([
ffmpeg_path, "-y",
"-v","verbose",
"-rw_timeout","10000000", # 10s
"-loglevel","error",
"-hide_banner",
"-user_agent",headers["User-Agent"],
"-analyzeduration","2147483647",
"-probesize","2147483647",
"-i",real_url,
'-bufsize','5000k',
"-map","0",
"-sn","-dn",
# "-f","mpegts",
# "-bsf:v","h264_mp4toannexb",
# "-c","copy",
"-c:v","libx264", #后期可以用crf来控制大小
#"-c:v","copy", #直接用copy的话体积特别大.
'-max_muxing_queue_size','64',
"{path}".format(path=file),
], stderr = subprocess.STDOUT)
else:
_output = subprocess.check_output([
ffmpeg_path, "-y",
"-v","verbose",
"-rw_timeout","10000000", # 10s
"-loglevel","error",
"-hide_banner",
"-user_agent",headers["User-Agent"],
"-analyzeduration","2147483647",
"-probesize","2147483647",
"-i",real_url,
'-bufsize','5000k',
"-map","0",
"-sn","-dn",
# "-f","mpegts",
# "-bsf:v","h264_mp4toannexb",
# "-c","copy",
#"-c:v","libx264", #后期可以用crf来控制大小
"-c:v","copy", #直接用copy的话体积特别大.
'-max_muxing_queue_size','64',
"{path}".format(path=file),
], stderr = subprocess.STDOUT)
recordfinish=True
recordfinish_2=True
counttime=time.time()
if startname in recording:
recording.remove(startname)
if startname in unrecording:
unrecording.add(startname)
except subprocess.CalledProcessError as exc:
#logging.warning(str(exc.output))
print(str(exc.output) +" 发生错误的行数: "+str(exc.__traceback__.tb_lineno) )
elif videosavetype=="MP3":
filename=startname + '_' + now + ".mp3"
if len(videopath)==0:
print("\r"+startname+" 录制音频中: "+os.getcwd()+"\\"+startname +'\\'+ filename)
else:
print("\r"+startname+" 录制音频中: "+videopath+startname +'\\'+ filename)
ffmpeg_path = "ffmpeg"
file = videopath+startname +'\\'+ filename
try:
recording.add(startname)
_output = subprocess.check_output([
ffmpeg_path, "-y",
"-rw_timeout","10000000", # 10s
"-user_agent",headers["User-Agent"],
"-i",real_url,
"{path}".format(path=file),
], stderr = subprocess.STDOUT)
recordfinish=True
recordfinish_2=True
counttime=time.time()
if startname in recording:
recording.remove(startname)
if startname in unrecording:
unrecording.add(startname)
except subprocess.CalledProcessError as exc:
#logging.warning(str(exc.output))
print(str(exc.output) +" 发生错误的行数: "+str(exc.__traceback__.tb_lineno) )
else:
if(Splitvideobysize): #这里默认是启用/不启用视频分割功能
while(True):
now = time.strftime("%Y-%m-%d-%H-%M-%S",time.localtime(time.time()))
filename=startname + '_' + now + ".ts"
if len(videopath)==0:
print("\r"+startname+" 分段录制视频中: "+os.getcwd()+"\\"+startname +'\\'+ filename + " 每录满: %d M 存一个视频"%Splitsize )
else:
print("\r"+startname+" 分段录制视频中: "+videopath+startname +'\\'+ filename+ " 每录满: %d M 存一个视频"%Splitsize)
ffmpeg_path = "ffmpeg"
file = videopath+startname +'\\'+ filename
try:
real_url=real_url.replace("\\u0026","&")
recording.add(startname)
_output = subprocess.check_output([
ffmpeg_path, "-y",
"-v","verbose",
"-rw_timeout","10000000", # 10s
"-loglevel","error",
"-hide_banner",
"-user_agent",headers["User-Agent"],
"-analyzeduration","2147483647",
"-probesize","2147483647",
"-i",real_url,
'-bufsize','5000k',
"-map","0",
"-sn","-dn",
"-f","mpegts",
# "-bsf:v","h264_mp4toannexb",
# "-c","copy",
"-c:v","copy",
'-max_muxing_queue_size','64',
"-fs",str(Splitsizes),
"{path}".format(path=file),
], stderr = subprocess.STDOUT)
recordfinish=True #这里表示正常录制成功一次
recordfinish_2=True
counttime=time.time() #这个记录当前时间, 用于后面 1分钟内快速2秒循环 这个值不能放到后面
if startname in recording:
recording.remove(startname)
if startname in unrecording:
unrecording.add(startname)
if tsconvertmp4:
threading.Thread(target=convertsmp4,args=(file,)).start()
except subprocess.CalledProcessError as exc:
#logging.warning(str(exc.output))
print(str(exc.output) +" 发生错误的行数: "+str(exc.__traceback__.tb_lineno) )
break
else:
filename=startname + '_' + now + ".ts"
if len(videopath)==0:
print("\r"+startname+" 录制视频中: "+os.getcwd()+"\\"+startname +'\\'+ filename)
else:
print("\r"+startname+" 录制视频中: "+videopath+startname +'\\'+ filename)
ffmpeg_path = "ffmpeg"
file = videopath+startname +'\\'+ filename
try:
recording.add(startname)
_output = subprocess.check_output([
ffmpeg_path, "-y",
"-v","verbose",
"-rw_timeout","10000000", # 10s
"-loglevel","error",
"-hide_banner",
# "-user_agent",headers["User-Agent"],
"-analyzeduration","2147483647",
"-probesize","2147483647",
"-i",real_url,
'-bufsize','5000k',
"-map","0",
"-sn","-dn",
"-f","mpegts",
# "-bsf:v","h264_mp4toannexb",
# "-c","copy",
"-c:v","copy",
'-max_muxing_queue_size','64',
"{path}".format(path=file),
], stderr = subprocess.STDOUT)
recordfinish=True
recordfinish_2=True
counttime=time.time()
if startname in recording:
recording.remove(startname)
if startname in unrecording:
unrecording.add(startname)
if tsconvertmp4:
threading.Thread(target=convertsmp4,args=(file,)).start()
except subprocess.CalledProcessError as exc:
#logging.warning(str(exc.output))
print(str(exc.output) +" 发生错误的行数: "+str(exc.__traceback__.tb_lineno) )
else:
#print('直播间不存在或未开播')
pass
if recordfinish_2==True:
if startname in recording:
recording.remove(startname)
if startname in unrecording:
unrecording.add(startname)
print('\n'+startname+" "+ time.strftime('%Y-%m-%d %H:%M:%S ') + '直播录制完成\n')
logger.warning(startname+" "+"直播录制完成")
recordfinish_2=False
x=delaydefault
if recordfinish==True:
counttimeend=time.time()-counttime
if counttimeend<60:
x=20 #现在改成默认20s
else:
recordfinish=False
else:
x=delaydefault
while x:
x = x-1
#print('\r循环等待%d秒 '%x)
if looptime:
print('\r循环等待%d秒 '%x ,end="")
time.sleep(1)
if looptime:
print('\r检测直播间中...',end="")
import datetime
start5 = datetime.datetime.now()
def displayinfo():
global start5
time.sleep(10)
while True:
time.sleep(30)
os.system("cls")
print("循环值守录制抖音直播 版本:%s"%str(version))
if len(recording)==0 and len(unrecording)==0:
time.sleep(10)
nowdate=time.strftime("%H:%M:%S", time.localtime())
print("\r没有正在录制的直播,请检查配置文件是否为空 "+nowdate,end="")
print("")
continue
else:
# livetask = len(recording) + len(unrecording)
# print("正则监控{}个直播".format(str(livetask)))
if len(recording)>0:
print("x"*60)
NoRepeatrecording = list(set(recording))
print("正在录制{}个直播: ".format(str(len(NoRepeatrecording))))
for x in NoRepeatrecording:
print(x+" 正在录制中")
#print("%i个直播正在录制中: "%len(NoRepeatrecording)+nowdate)
end = datetime.datetime.now()
print('总共录制时间: ' +str(end - start5))
print("x"*60)
else:
start5 = datetime.datetime.now()
# if len(unrecording)>0:
# NounRepeatrecording = list(set(unrecording))
# for x in NounRepeatrecording:
# #logger.warning(x+" 直播间未直播,等待开播中.. ")
# print(x+" :等待直播中")
# print("x"*60)
# time.sleep(10)
t = threading.Thread(target=displayinfo, args=(), daemon=True)
t.start()
runingList=[]
texturl=[]
textNoRepeatUrl=[]
createVar = locals()
zz=0
namelist=[]
while True:
file=open("URL_config.ini","r",encoding="utf-8-sig")
for line in file:
line=line.strip()
if line.startswith("#"):
continue
c=line.split()
if len(c)==0:
continue
else:
c=line.strip()
c=c.split('#')
if len(line)<20:
continue
texturl.append(line)
#print(c[0])
while len(namelist):
a=namelist.pop()
replacewords = a.split('|')
updateFile(r"URL_config.ini", replacewords[0], replacewords[1])
#格式化后查找不一样
file.close()
if len(texturl)>0:
textNoRepeatUrl = list(set(texturl))
if len(textNoRepeatUrl)>0:
for i in textNoRepeatUrl:
formatcontent = i.split(',')
#formatcontent[0] #这个为分离出的地址
if formatcontent[0] not in runingList:
#print("新增链接: "+ formatcontent[0])
zz=zz+1
createVar['thread'+ str(zz)] = threading.Thread(target=startgo,args=(i,))
createVar['thread'+ str(zz)].setDaemon(True)
createVar['thread'+ str(zz)].start()
runingList.append(formatcontent[0])
time.sleep(1.5)
texturl=[]
time.sleep(3)
#print('程式结束,请按任意键退出')
input()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册