Skip to content

Commit 8b603ae

Browse files
authored
Merge pull request #3 from MarkusLuan/update2
Update2 - Exibindo retorno de vídeo e o tempo restante do stream
2 parents 2c56614 + fbab0cc commit 8b603ae

File tree

12 files changed

+241
-5
lines changed

12 files changed

+241
-5
lines changed

instagram/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ def atualizarCSRFToken(token):
3030
from .login import LoginMgr
3131
from .comentario import ComentarioMgr
3232
from .stream import Stream
33+
from .midia import Midia
3334
from .model.usuario import Usuario
3435

36+
Midia = Midia(getSession)
37+
3538
def getJoinRequests(self, stream, last_joinRequest):
3639
session = getSession()
3740

instagram/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ class Constants:
66
"""
77

88
APP_VERSION = '76.0.0.15.395'
9+
WIN_VERSION = "10.0"
10+
CHROME_VERSION = "83.0.4103.106"
911

1012
ANDROID_VERSION = 24
1113
ANDROID_RELEASE = '7.0'

instagram/midia.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from .constants import Constants
2+
import os
3+
4+
class Midia:
5+
def __init__(self, getSession):
6+
self.__getSession = getSession
7+
8+
def info(self, stream_id):
9+
self.__session = self.__getSession()
10+
11+
usuario = self.__session.cookies["ds_user"]
12+
13+
req = self.__session.get("https://i.instagram.com/api/v1/live/%s/info" % stream_id)
14+
res = req.json()
15+
url = res["dash_playback_url"]
16+
17+
req = self.__session.get(url)
18+
res = url + "\n"
19+
res += req.text
20+
return res
21+
22+
def __lerMidia(self, url):
23+
url = "https://instagram.fnat1-1.fna.fbcdn.net/hvideo-" + url
24+
req = self.__session.get(url, stream=True, headers={
25+
'Accept': '*/*'
26+
})
27+
req.raise_for_status()
28+
return req.content
29+
30+
def midia(self, url, stream_id, iniciado):
31+
self.__session = self.__getSession()
32+
33+
initFile = os.path.expandvars("%temp%\\")
34+
initFile += ".midia_" + stream_id + "-init." + url[-3:]
35+
content = bytes()
36+
37+
# Se o arquivo solicitado não for o init, retorne os bytes
38+
# Se o arquivo solicitado for o init e não tiver sido baixado, faça o download e retorne os bytes
39+
if not url[-8:].startswith("init"):
40+
content = self.__lerMidia(url)
41+
elif not os.path.isfile(initFile):
42+
content = self.__lerMidia(url)
43+
44+
f = open(initFile, "wb")
45+
f.write(content)
46+
f.close()
47+
return content
48+
elif not iniciado: # Se o arquivo solicitado for o init e tiver sido baixado, leia e retorne os bytes
49+
f = open(initFile, "rb")
50+
content = f.read()
51+
f.close()
52+
53+
return content

instagram/stream.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from .constants import Constants
22
import requests
33
from flask import request
4+
from datetime import datetime
45

56
class Stream():
67
def __init__(self, getSession, criarStream=True):
@@ -9,13 +10,15 @@ def __init__(self, getSession, criarStream=True):
910
self.url = None
1011
self.key = None
1112
self.iniciado = False
13+
self.startTime = None
1214
self.__cookies = {}
1315

1416
if not criarStream:
1517
self.id = request.cookies.get("stream_id")
1618
self.url = request.cookies.get("stream_url")
1719
self.key = request.cookies.get("stream_key")
1820
self.iniciado = request.cookies.get("stream_status")
21+
self.startTime = request.cookies.get("stream_startTime")
1922

2023
self.iniciado = (self.iniciado == "iniciado")
2124

@@ -76,6 +79,7 @@ def iniciar(self):
7679
self.__cookies.update({"csrf_token": token})
7780

7881
self.iniciado = True
82+
self.startTime = int(datetime.now().timestamp())
7983

8084
def encerrar(self):
8185
self.__session = self.__getSession()

main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
from login import Login
88
from stream import Stream
99
from comentario import Comentario
10+
from midia import Midia
1011

1112
app = Flask(__name__)
1213

1314
login = Login(app)
1415
stream = Stream(app, login)
1516
comentario = Comentario(app, login, stream)
17+
midia = Midia(app, stream)
1618

1719
@app.route("/")
1820
def index():

midia.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import instagram
2+
from flask import request, redirect, render_template, make_response, Response, stream_with_context
3+
import xmltodict
4+
5+
class Midia:
6+
def __init__(self, app, stream):
7+
self.__stream = stream
8+
self.rotas(app)
9+
10+
def __info(self):
11+
stream = self.__stream.value
12+
13+
#Recebendo informações dos videos e audios e a url principal
14+
videoInfo = instagram.Midia.info(stream.id)
15+
16+
#Separando url
17+
url = videoInfo[:videoInfo.index("\n")]
18+
videoInfo = videoInfo.replace(url + "\n", "")
19+
20+
#Tratando mpd
21+
url = url[:url.rindex("/")]
22+
url = url[:url.rindex("/")+1]
23+
url = url.replace("https://instagram.fnat1-1.fna.fbcdn.net/hvideo-", "")
24+
videoInfo = videoInfo.replace("../", url)
25+
26+
videoInfo = xmltodict.parse(videoInfo)
27+
28+
root = videoInfo["MPD"]["Period"]["AdaptationSet"]
29+
v = root[0]["Representation"]
30+
a = root[1]["Representation"]
31+
32+
v_type = v["@mimeType"]
33+
a_type = a["@mimeType"]
34+
35+
v = v["SegmentTemplate"]
36+
a = a["SegmentTemplate"]
37+
38+
v_url = v["@media"].replace("../", "")
39+
a_url = a["@media"].replace("../", "")
40+
41+
v = v["SegmentTimeline"]["S"]
42+
a = a["SegmentTimeline"]["S"]
43+
44+
videos = [{
45+
"duration": 0,
46+
"url": v_url.replace("$Time$", "init"),
47+
"mime_type": v_type
48+
}]
49+
50+
audios = [{
51+
"duration": 0,
52+
"url": a_url.replace("$Time$", "init"),
53+
"mime_type": v_type
54+
}]
55+
56+
for _v in v:
57+
videos.append({
58+
"duration": _v["@d"],
59+
"url": v_url.replace("$Time$", _v["@t"]),
60+
"mime_type": v_type
61+
})
62+
63+
for _a in a:
64+
audios.append({
65+
"duration": _a["@d"],
66+
"url": a_url.replace("$Time$", _a["@t"]),
67+
"mime_type": v_type
68+
})
69+
70+
midia = {
71+
"videos": videos,
72+
"audios": audios
73+
}
74+
75+
return midia
76+
77+
def __midia(self, url, iniciado):
78+
stream = self.__stream.value
79+
return instagram.Midia.midia(url, stream.id, iniciado)
80+
81+
def rotas(self, app):
82+
def getMidiaContent(k, iniciado=False):
83+
midia = self.__info()
84+
content = bytes()
85+
86+
for m in midia[k]:
87+
content += self.__midia(m["url"], iniciado)
88+
iniciado = True
89+
return content
90+
91+
def genMidia(k):
92+
iniciado = False
93+
with app.app_context():
94+
while self.__stream.value is not None:
95+
content = getMidiaContent(k)
96+
iniciado = True
97+
yield content
98+
99+
100+
@app.route("/midia/video")
101+
def getVideo():
102+
return Response(stream_with_context(genMidia("videos")))
103+
104+
@app.route("/midia/audio")
105+
def getAudio():
106+
return make_response(
107+
getMidiaContent("audios"),
108+
200,
109+
{
110+
"content-type": "audio/mp4"
111+
}
112+
)

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Para encerrar o servidor basta aperta *"ctrl" + "c"* no cmd ou terminal.
2626
- Ver os comentários em tempo real
2727
- Comentar
2828
- Ocultar/Exibir comentários
29+
- Exibir retorno do vídeo
30+
- Exibindo tempo restante para o limite de 1 hora no Instagram
2931

3032
### Script Baseado Nestes Repositórios
3133
- [Instagram-PHP-API](https://github.com/cosenary/Instagram-PHP-API)

requeriments.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
certifi==2020.4.5.1
22
chardet==3.0.4
33
click==7.1.2
4+
decorator==4.4.2
45
Flask==1.1.2
56
idna==2.9
7+
install==1.3.3
68
itsdangerous==1.1.0
79
Jinja2==2.11.2
810
MarkupSafe==1.1.1
11+
numpy==1.19.0
912
requests==2.23.0
13+
tqdm==4.47.0
1014
urllib3==1.25.9
1115
Werkzeug==1.0.1
16+
xmltodict==0.12.0

static/css/index.css

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ input[type="text"]{
3232
#comentarios{
3333
height: 400px;
3434
overflow-y: auto;
35+
border-left: solid 1px;
36+
padding-left: 17px;
3537
}
3638

3739
#comentarios div{
@@ -59,6 +61,22 @@ input[type="text"]{
5961
top: -6px;
6062
}
6163

64+
#player{
65+
float: left;
66+
margin: 15px;
67+
margin-right: 71px;
68+
}
69+
70+
#div_tRestante{
71+
background-color: #983a3a;
72+
width: 120px;
73+
color: #FFFFFF;
74+
text-align: center;
75+
border-radius: 10px;
76+
padding: 8px;
77+
margin-left: 47px;
78+
}
79+
6280
@keyframes
6381
comentario_anim{
6482
from{

static/js/stream.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,21 @@ function getInfo(){
2323
setTimeout(getInfo, 1500);
2424
}
2525
});
26-
}
26+
}
27+
28+
function atualizarTRestante(){
29+
setInterval(function(){
30+
var now = new Date().getTime();
31+
var dif = startTime - now;
32+
dif = new Date(dif);
33+
dif.setHours(0);
34+
35+
var options = {
36+
"hour": "numeric",
37+
"minute": "numeric",
38+
"second": "numeric"
39+
};
40+
document.getElementById("tRestante").innerText = dif.toLocaleString("pt-BR", options);
41+
}, 1000);
42+
}
43+

0 commit comments

Comments
 (0)