HLS直播预取视频并更新m3u8
#!/usr/bin/python27
import json
import threading
import urllib
import sys
import hashlib
import time
import commands
class myThread(threading.Thread):
def __init__(self, url):
threading.Thread.__init__(self)
self.url=url
self.u2="%s%s"%(s,self.url)
def run(self):
fmd5=''
while True:
try:
urltmp=''
f=urllib.urlopen(self.u2).read()
ftmp=hashlib.md5(f).hexdigest()
#print fmd5,ftmp
if fmd5!=ftmp:
u3=self.u2.split('/')
u3=self.u2.replace(u3[-1],'')
lofile=f.split('\n')[-2]
u3=u3.replace(s,lo)
tsurl="%s%s"%(u3,lofile)
#get m3u8 and create
p='/opt/hls_live/web'
m3u8_path='%s%s'%(p,self.url)
try:
tmpf=file(m3u8_path,'r+')
except IOError:
tmpf=file(m3u8_path,'w+')
r1=tmpf.read()
tmpf.close()
if r1.find('ENDLIST')==-1:
urltmp=urllib.urlopen(tsurl)
time.sleep(0.5)
tmpf=file(m3u8_path,'w')
tmpf.write(f)
#os.chown(m3u8_path,99,99)
tmpf.close()
fmd5=ftmp
time.sleep(0.5)
except:
continue
def stop(self):
self.stopped=True
def get_channels(a=0):
url=[]
channels=urllib.urlopen('http://127.0.0.1:8010/channels').read()
channels=channels.replace('\'','"')
c=json.loads(channels)
for i in c:
status=c[i][1]
u=c[i][0].split('web')
u=u[1]
if a==1: #get all channels for exception
url.append(u)
elif status=='on':
url.append(u)
return url
def test():
global lo,s
s='http://180.xxx.xxx.3:8008' #后端文件读取HTTP地址
lo='http://127.0.0.1:8008'
allurl=get_channels(1)
url=get_channels()
exurl=url
for u in url:
t=myThread(u)
t.start()
import signal,os
class Watcher:
"""this class solves two problems with multithreaded
programs in Python, (1) a signal might be delivered
to any thread (which is just a malfeature) and (2) if
the thread that gets the signal is waiting, the signal
is ignored (which is a bug).
The watcher is a concurrent process (not thread) that
waits for a signal and the process that contains the
threads. See Appendix A of The Little Book of Semaphores.
http://greenteapress.com/semaphores/
I have only tested this on Linux. I would expect it to
work on the Macintosh and not work on Windows.
"""
def __init__(self):
""" Creates a child thread, which returns. The parent
thread waits for a KeyboardInterrupt and then kills
the child thread.
"""
self.child = os.fork()
if self.child == 0:
return
else:
self.watch()
def watch(self):
try:
os.wait()
except KeyboardInterrupt:
# I put the capital B in KeyBoardInterrupt so I can
# tell when the Watcher gets the SIGINT
print 'KeyBoardInterrupt'
self.kill()
sys.exit()
def kill(self):
try:
os.kill(self.child, signal.SIGKILL)
except OSError: pass
if __name__== '__main__':
cmd="kill -9 `cat /opt/hls_live/web/livehttp.pid`"
status,returncmd=commands.getstatusoutput(cmd)
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
# decouple from parent environment
os.chdir("/")
os.setsid()
os.umask(0)
os.setuid(99)
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent, print eventual PID before
print "Start OK..."
pidfile=open('/opt/hls_live/web/http.pid','w')
pidfile.write(str(pid))
pidfile.close()
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
#Watcher()
test()