コード例 #1
0
         process.kill()
 subprocess.Popen([
     "cvlc",
     response['response']['playback_url'],
     "--sout",
     "#std{access=file,mux=ts,dst='/tmp/acestream.mkv'}"
 ])
 time.sleep(30)  #30s sample video
 for process in psutil.process_iter():
     if '/usr/bin/vlc' in process.cmdline():
         process.kill()
 info = MediaInfo(
     filename='/tmp/acestream.mkv')
 language = ""
 try:
     infoData = info.getInfo()
     proc = subprocess.Popen(
         [
             "/usr/bin/mediainfo",
             "/tmp/acestream.mkv"
         ],
         stdout=subprocess.PIPE)
     o = proc.stdout.read()
     for l in o.split("\n"):
         if re.match("Language", l):
             language = l.split(":")[1][1:]
     #print infoData
 except:
     infoData = {}
 if 'bitrate' not in infoData: score = 0
 else:
コード例 #2
0
    def do_GET(self):
        global temp_stream_saved, file_save_status, key, streamtimer, dir_path
        if not os.path.isfile('/tmp/pid_stat_url'):
            with open('/tmp/pid_stat_url', 'w') as f:
                f.write(json.dumps(None))
        with open('/tmp/pid_stat_url', 'r') as f:
            pid_stat_url = json.loads(f.read())
        path = self.path.split("/")
        if path[1] != 'segments':  #allow non-password access to live stream segments
            if self.headers.getheader('Authorization') == None:
                self.do_AUTHHEAD()
                pass
            elif self.headers.getheader('Authorization') != "Basic %s" % key:
                self.do_AUTHHEAD()
                pass
            if self.headers.getheader('Authorization') != "Basic %s" % key:
                return

        #check if vlc running
        vlcrunning = False
        for process in psutil.process_iter():
            if '/usr/bin/vlc' in process.cmdline(
            ) and '--live-caching' in process.cmdline():
                vlcrunning = True
                vlcrunning_line = process.cmdline()
        enginerunning = False
        if "acestreamengine" in (p.name() for p in psutil.process_iter()):
            enginerunning = True

        if path[1] == 'engine':
            if len(path) == 3:
                if path[2] == 'start' and enginerunning == False:
                    proc1 = subprocess.Popen([
                        "/snap/bin/acestreamplayer.engine", "--client-console",
                        "--live-cache-type", "disk", "--live-disk-cache-size",
                        "1000000000"
                    ])
                elif path[2] == 'stop':
                    for process in psutil.process_iter():
                        if process.name() == "acestreamengine" or (
                                '/usr/bin/vlc' in process.cmdline()
                                and '--live-caching' in process.cmdline()):
                            process.kill()
                    pid_stat_url = None
                    with open('/tmp/pid_stat_url', 'w') as f:
                        f.write(json.dumps(pid_stat_url))
                    if os.path.isfile(dir_path + "/listings/LIVE.strm"):
                        os.remove(dir_path + "/listings/LIVE.strm")
                elif path[2] == 'stopstream':
                    for process in psutil.process_iter():
                        if '/usr/bin/vlc' in process.cmdline(
                        ) and '--live-caching' in process.cmdline():
                            process.kill()
                    if pid_stat_url is not None:
                        #command_url ?method=stop
                        sr = requests.get(
                            json.loads(pid_stat_url[3])['response']
                            ['command_url'] + "?method=stop")
                        #print sr.text
                    pid_stat_url = None
                    with open('/tmp/pid_stat_url', 'w') as f:
                        f.write(json.dumps(pid_stat_url))
                    if os.path.isfile(dir_path + "/listings/LIVE.strm"):
                        os.remove(dir_path + "/listings/LIVE.strm")

                time.sleep(5)
                self.send_response(302)
                self.send_header('Location', "/")
                self.end_headers()

        elif path[1] == 'transcoding' and pid_stat_url is not None:
            if len(path) == 3:
                if path[2] == 'start' and len(pid_stat_url) > 0:
                    if vlcrunning == False:  #only start one instance
                        temp_stream_saved = False
                        f = open(dir_path + "/listings/LIVE.strm", "w")
                        f.write("%s://%s:%s@%s/segments/acestream.m3u8" %
                                (PROTOCOL, USERNAME, PASSWORD, SERVER_IP))
                        f.close()
                        subprocess.Popen([
                            "cvlc", "--live-caching", "30000", pid_stat_url[2],
                            "--sout",
                            "#duplicate{dst=std{access=livehttp{seglen=5,delsegs=true,numsegs=20,index="
                            + dir_path +
                            "/segments/acestream.m3u8,index-url=" + PROTOCOL +
                            "://" + USERNAME + ":" + PASSWORD + "@" +
                            SERVER_IP +
                            "/segments/stream-########.ts},mux=ts{use-key-frames},dst="
                            + dir_path +
                            "/segments/stream-########.ts},dst=std{access=file,mux=ts,dst='"
                            + dir_path +
                            "/listings/live_stream_from_start.mp4'}}"
                        ])
                elif path[2] == 'stop' and len(pid_stat_url) > 0:
                    for process in psutil.process_iter(
                    ):  #kill acestream engine and vlc
                        if process.name() == "acestreamengine" or (
                                '/usr/bin/vlc' in process.cmdline()
                                and '--live-caching' in process.cmdline()):
                            process.kill()
                    pid_stat_url = None
                    with open('/tmp/pid_stat_url', 'w') as f:
                        f.write(json.dumps(pid_stat_url))
                    if os.path.isfile(dir_path + "/listings/LIVE.strm"):
                        os.remove(dir_path + "/listings/LIVE.strm")
                    temp_stream_saved = True
                time.sleep(5)
                self.send_response(302)
                self.send_header('Location', "/")
                self.end_headers()

        elif path[1] == 'savefile' and len(path) == 3:
            for f in path[2].split("?")[1].split("&"):
                if f.split("=")[0] == "savefilename":
                    matchname = f.split("=")[1]
            for process in psutil.process_iter():
                if process.name() == "acestreamengine" or (
                        '/usr/bin/vlc' in process.cmdline()
                        and '--live-caching' in process.cmdline()):
                    process.kill()
            #ffmpeg has needed -bsf:a aac_adtstoasc option to fix  PES packet size mismatch, Error parsing ADTS frame header errors only for AAC audio
            info = MediaInfo(filename=dir_path +
                             "/listings/live_stream_from_start.mp4")
            try:
                if info.getInfo()['audioCodec'] == "AAC":
                    file_save_status = [
                        "ffmpeg", "-y", "-i",
                        dir_path + "/listings/live_stream_from_start.mp4",
                        "-c:v", "copy", "-c:a", "copy", "-movflags",
                        "faststart", "-bsf:a", "aac_adtstoasc",
                        dir_path + "/listings/" + matchname + ".mp4"
                    ]
                else:
                    file_save_status = [
                        "ffmpeg", "-y", "-i",
                        dir_path + "/listings/live_stream_from_start.mp4",
                        "-c:v", "copy", "-c:a", "copy", "-movflags",
                        "faststart",
                        dir_path + "/listings/" + matchname + ".mp4"
                    ]
            except:
                file_save_status = [
                    "ffmpeg", "-y", "-i",
                    dir_path + "/listings/live_stream_from_start.mp4", "-c:v",
                    "copy", "-c:a", "copy", "-movflags", "faststart",
                    dir_path + "/listings/" + matchname + ".mp4"
                ]
            subprocess.Popen(file_save_status)
            pid_stat_url = None
            with open('/tmp/pid_stat_url', 'w') as f:
                f.write(json.dumps(pid_stat_url))
            temp_stream_saved = False
            self.send_response(302)
            self.send_header('Location', "/")
            self.end_headers()

        elif path[1] == 'openpid' and len(path) == 3 and enginerunning:
            for process in psutil.process_iter():  #kill any vlc session
                if '/usr/bin/vlc' in process.cmdline(
                ) and '--live-caching' in process.cmdline():
                    process.kill()
            pid_stat_url = None
            with open('/tmp/pid_stat_url', 'w') as f:
                f.write(json.dumps(pid_stat_url))
            stream_pid = False
            for f in path[2].split("?")[1].split("&"):
                if f.split("=")[0] == "pid":
                    stream_pid = f.split("=")[1]
                    stream_uid = hashlib.sha1(stream_pid).hexdigest()
            if stream_pid:
                r = requests.get(
                    'http://127.0.0.1:6878/ace/getstream?format=json&sid={0}&id={1}'
                    .format(stream_uid, stream_pid))
                pid_stat_url = [
                    stream_pid,
                    json.loads(r.text)['response']['stat_url'],
                    json.loads(r.text)['response']['playback_url'], r.text,
                    stream_pid
                ]
                with open('/tmp/pid_stat_url', 'w') as f:
                    f.write(json.dumps(pid_stat_url))

            #start stream timer
            streamtimer = time.time()
            time.sleep(5)
            self.send_response(302)
            self.send_header('Location', "/")
            self.end_headers()

        else:
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            self.wfile.write("""
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body{
  font-family: Arial;
  font-size:12px;
  text-align:center;
}
.button {
    background-color: #4CAF50;
    border: none; 
    color: white; 
    padding: 12px 24px; 
    font-size: 12px;
    cursor: pointer;
    width:150px;
    text-align:left;
}
.buttonloading {
    background-color: #4CAF50;
    }
.buttonstopped{
    background-color: #AF504C
    }
  
.fa {
    margin-left: -12px;
    margin-right: 8px;
}
.status{
    font-family:Courier;
    font-size:80%;
}
.statusdiv{
    margin:auto;
    text-align:center;
    width:400px;
    padding-top:10px;
    padding-bottom:20px;
    font-family: Courier;
    font-weight: bold;
}
</style>
</head>
<body>
""")
            self.wfile.write("<div>")
            disabledtext = ["", ""]
            if enginerunning:
                disabledtext[0] = "disabled style='opacity: 0.4;'"
                engine_status_text = "Running"
            else:
                disabledtext[1] = "disabled style='opacity: 0.4;'"
                engine_status_text = "Not running"
            self.wfile.write("""
        <button class='button buttonloading' %s onclick='this.style.display=\"none\";document.getElementById(\"button_starting\").style.display=\"\";location.href="/engine/start\"'>
        <i class='fa fa-stop-circle'></i>Start Engine</button>
       <button id='button_starting' class='button buttonloading' style='display:none'> 
        <i class='fa fa-spinner fa-spin'></i>Starting Engine</button>
       """ % disabledtext[0])
            self.wfile.write("""
        <button class='button buttonstopped' %s onclick='this.style.display=\"none\";document.getElementById(\"button_stopping\").style.display=\"\";location.href="/engine/stop\"'>
        <i class='fa fa-play-circle'></i>Stop Engine</button>
        <button id='button_stopping' class='button buttonloading' style='display:none'> 
        <i class='fa fa-spinner fa-spin'></i>Stopping Engine</button>
        """ % disabledtext[1])

            self.wfile.write(
                "</div><div class='statusdiv'>Engine Status: %s</div>" %
                engine_status_text)

            disabledtext = ["", ""]
            stream_OK_to_transcode = False
            if enginerunning:
                if pid_stat_url is not None:
                    s = requests.get(pid_stat_url[1])
                    engine_response = json.loads(s.text)
                    disabledtext[0] = "disabled style='opacity: 0.4;'"
                    acestream_status_text = "Streaming<br />acestream://%s<br />" % pid_stat_url[
                        0]
                    if (time.time() - streamtimer) < 30:
                        acestream_status_text += "Wait 30s for stream to settle<br />"
                        acestream_status_text += """
            <script>
            var timeleft = 30;
            var downloadTimer = setInterval(function(){
              document.getElementById("progressBar").value = 30 - --timeleft;
              if(timeleft <= 0){
                clearInterval(downloadTimer);
                location.href="/";
              }
            },1000);
            </script>
            <progress value="0" max="30" id="progressBar"></progress>
            <br />
            """
                    elif 'response' in engine_response:
                        if 'speed_down' in engine_response['response']:
                            if engine_response['response'][
                                    'status'] == "prebuf":
                                acestream_status_text += "Buffering"
                            elif int(engine_response['response']
                                     ['speed_down']) < 100:
                                acestream_status_text += "Stream health poor"
                            elif int(engine_response['response']
                                     ['speed_down']) < 300:
                                acestream_status_text += "Stream health average"
                                stream_OK_to_transcode = True
                            else:
                                acestream_status_text += "Stream health OK"
                                stream_OK_to_transcode = True
                            if stream_OK_to_transcode:
                                acestream_status_text += "<br />DL Speed: %s kbps<br />Peers %s" % (
                                    engine_response['response']['speed_down'],
                                    engine_response['response']['peers'])
                            else:  #reload every 5 seconds if buffering or poor stream health
                                self.wfile.write("""<script>
                  setTimeout(function(){
                    window.location.reload(1);
                  }, 5000);
                  </script>""")

                else:
                    disabledtext[1] = "disabled style='opacity: 0.4;'"
                    acestream_status_text = "No stream"
            else:
                disabledtext[0] = "disabled style='opacity: 0.4;'"
                disabledtext[1] = "disabled style='opacity: 0.4;'"
                acestream_status_text = ""
            self.wfile.write(
                '<div><form method="GET" action="/openpid/" id="openpid" style="display:inline"><input type=text name="pid" placeholder="Acestream ID" style="margin-bottom:10px;width:300px;" %s><br>'
                % disabledtext[0])
            self.wfile.write("""
        <button class='button buttonloading' %s onclick='this.style.display="none"; document.getElementById("button_ace_starting").style.display=""; document.getElementById("openpid").submit()'>
        <i class='fa fa-stop-circle'></i>Start Acestream</button>
        <button id='button_ace_starting' class='button buttonloading' style='display:none'>
        <i class='fa fa-spinner fa-spin'></i>Starting Acestream</button></form>
      """ % disabledtext[0])
            self.wfile.write("""
        <button class='button buttonstopped' %s onclick='this.style.display="none";document.getElementById("button_ace_stopping").style.display="";location.href="/engine/stopstream"'>
        <i class='fa fa-play-circle'></i>Stop Acestream</button>
        <button id="button_ace_stopping" class='button buttonstopped' style='display:none'> 
        <i class='fa fa-spinner fa-spin'></i>Stopping Acestream</button>
        """ % disabledtext[1])
            self.wfile.write(
                "</div><div class='statusdiv'>Acestream Status: %s</div>" %
                acestream_status_text)

            self.wfile.write("<div>")
            disabledtext = ["", ""]
            if stream_OK_to_transcode:
                if vlcrunning:
                    disabledtext[0] = "disabled style='opacity: 0.4;'"
                    transcode_status_text = """
          Transcoding<br />Stream: %s://%s/segments/acestream.m3u8<br />
          Kodi: %s://%s/listings/LIVE.strm<br />
          """ % (PROTOCOL, SERVER_IP, PROTOCOL, SERVER_IP)
                else:
                    disabledtext[1] = "disabled style='opacity: 0.4;'"
                    transcode_status_text = "Not Transcoding"
            else:
                disabledtext[0] = "disabled style='opacity: 0.4;'"
                disabledtext[1] = "disabled style='opacity: 0.4;'"
                transcode_status_text = ""
            self.wfile.write("""
        <button class='button buttonloading' %s onclick='this.style.display=\"none\";document.getElementById(\"transcode_starting\").style.display=\"\";location.href="/transcoding/start\"'>
        <i class='fa fa-stop-circle'></i>Start Transcode</button>
       <button id='transcode_starting' class='button buttonloading' style='display:none'> 
        <i class='fa fa-spinner fa-spin'></i>Starting Transcode</button>
       """ % disabledtext[0])
            self.wfile.write("""
        <button class='button buttonstopped' %s onclick='this.style.display=\"none\";document.getElementById(\"transcode_stopping\").style.display=\"\";location.href="/transcoding/stop\"'>
        <i class='fa fa-play-circle'></i>Stop Transcode</button>
        <button id='transcode_stopping' class='button buttonloading' style='display:none'> 
        <i class='fa fa-spinner fa-spin'></i>Stopping Trancode</button>
        """ % disabledtext[1])

            self.wfile.write(
                "</div><div class='statusdiv'>Transcode Status: %s</div>" %
                transcode_status_text)

            if vlcrunning: disabledtext[0] = ""
            else: disabledtext[0] = "disabled style='opacity: 0.4;'"
            self.wfile.write(
                "<button class='button buttonloading' %s onclick='window.open(\"%s://%s/player.html\", \"\", \"width=660,height=380\");'><i class='fa fa-play-circle'></i>Launch Player</button>"
                % (disabledtext[0], PROTOCOL, SERVER_IP))

            if not temp_stream_saved:
                disabledtext[0] = "disabled style='opacity: 0.4;'"
            else:
                disabledtext[0] = ""
            self.wfile.write('''
       <div>
       <form method="GET" action="/savefile/" id="savefile">
       <input type=text name="savefilename" placeholder="Save filename" style="margin-top:20px; margin-bottom:10px;width:300px;" %s><br />
       <button class='button buttonloading' %s onclick='document.getElementById("savefile").submit()'>
       <i class='fa fa-save'></i>Save Recording</button>
       </form>
       </div>
      ''' % (disabledtext[0], disabledtext[0]))
コード例 #3
0
                     with open('/tmp/pid_stat_url', 'w') as f:
                         f.write(json.dumps(pid_stat_url))
                     #check is playing, if so transcode approriate length
                     time.sleep(2)
                     subprocess.Popen([
                         "cvlc", response['response']['playback_url'],
                         "--sout",
                         "#std{access=file,mux=ts,dst='/tmp/acestream.mkv'}"
                     ])
                     time.sleep(time_to_record * 60)
 for process in psutil.process_iter():
     if '/usr/bin/vlc' in process.cmdline():
         process.kill()
 info = MediaInfo(filename='/tmp/acestream.mkv')
 try:
     if info.getInfo()['audioCodec'] == "AAC":
         file_save_status = [
             "ffmpeg", "-y", "-i", "/tmp/acestream.mkv", "-c:v", "copy",
             "-c:a", "copy", "-movflags", "faststart", "-bsf:a",
             "aac_adtstoasc", dir_path + "/listings/" + matchname + ".mp4"
         ]
     else:
         file_save_status = [
             "ffmpeg", "-y", "-i", "/tmp/acestream.mkv", "-c:v", "copy",
             "-c:a", "copy", "-movflags", "faststart",
             dir_path + "/listings/" + matchname + ".mp4"
         ]
 except:
     file_save_status = [
         "ffmpeg", "-y", "-i", "/tmp/acestream.mkv", "-c:v", "copy", "-c:a",
         "copy", "-movflags", "faststart",
コード例 #4
0
ファイル: tests.py プロジェクト: pharvie/scraper
    def test_haveDefaultCmdFfprobe(self):
        info = MediaInfo(filename='/media/test.ts')
        infoData = info.getInfo()

        self.assertNotEqual(infoData, None)
コード例 #5
0
ファイル: tests.py プロジェクト: pharvie/scraper
    def test_haveCmdParameter(self):
        info = MediaInfo(filename='/media/test.ts', cmd='/usr/bin/ffprobe')
        infoData = info.getInfo()

        self.assertNotEqual(infoData, None)
コード例 #6
0
ファイル: tests.py プロジェクト: pharvie/scraper
    def test_nonFileNameParameter(self):
        info = MediaInfo()
        infoData = info.getInfo()

        self.assertEqual(infoData, None)