Skip to content

Commit 36f3edf

Browse files
committed
Add function uploadVideo
1 parent 92c3b80 commit 36f3edf

File tree

1 file changed

+89
-5
lines changed

1 file changed

+89
-5
lines changed

InstagramAPI.py

+89-5
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@
88
import urllib
99
import uuid
1010
import time
11+
import copy
12+
import math
1113
from ImageUtils import getImageSize
1214
from requests_toolbelt import MultipartEncoder
15+
from moviepy.editor import VideoFileClip
1316

1417
class InstagramAPI:
1518
API_URL = 'https://i.instagram.com/api/v1/'
@@ -134,17 +137,98 @@ def uploadPhoto(self, photo, caption = None, upload_id = None):
134137
self.expose()
135138
return False
136139

137-
def uploadVideo(self, video, caption = None):
138-
# TODO Instagram.php 290-415
140+
def uploadVideo(self, video, thumbnail, caption = None, upload_id = None):
141+
if upload_id is None:
142+
upload_id = str(int(time.time() * 1000))
143+
data = {
144+
'upload_id': upload_id,
145+
'_csrftoken': self.token,
146+
'media_type': '2',
147+
'_uuid': self.uuid,
148+
}
149+
m = MultipartEncoder(data, boundary=self.uuid)
150+
self.s.headers.update({'X-IG-Capabilities': '3Q4=',
151+
'X-IG-Connection-Type': 'WIFI',
152+
'Host': 'i.instagram.com',
153+
'Cookie2': '$Version=1',
154+
'Accept-Language': 'en-US',
155+
'Accept-Encoding': 'gzip, deflate',
156+
'Content-type': m.content_type,
157+
'Connection': 'keep-alive',
158+
'User-Agent': self.USER_AGENT})
159+
response = self.s.post(self.API_URL + "upload/video/", data=m.to_string())
160+
if response.status_code == 200:
161+
body = json.loads(response.text)
162+
upload_url = body['video_upload_urls'][3]['url']
163+
upload_job = body['video_upload_urls'][3]['job']
164+
165+
videoData = open(video, 'rb').read()
166+
request_size = math.floor(len(videoData) / 4)
167+
lastRequestExtra = (len(videoData) - (request_size * 3))
168+
169+
headers = copy.deepcopy(self.s.headers)
170+
self.s.headers.update({'X-IG-Capabilities': '3Q4=',
171+
'X-IG-Connection-Type': 'WIFI',
172+
'Cookie2': '$Version=1',
173+
'Accept-Language': 'en-US',
174+
'Accept-Encoding': 'gzip, deflate',
175+
'Content-type': 'application/octet-stream',
176+
'Session-ID': upload_id,
177+
'Connection': 'keep-alive',
178+
'Content-Disposition': 'attachment; filename="video.mov"',
179+
'job': upload_job,
180+
'Host': 'upload.instagram.com',
181+
'User-Agent': self.USER_AGENT})
182+
for i in range(0, 4):
183+
start = i * request_size
184+
if i == 3:
185+
end = i * request_size + lastRequestExtra
186+
else:
187+
end = (i + 1) * request_size
188+
length = lastRequestExtra if i == 3 else request_size
189+
content_range = "bytes {start}-{end}/{lenVideo}".format(start=start, end=(end - 1),
190+
lenVideo=len(videoData)).encode('utf-8')
191+
192+
self.s.headers.update({'Content-Length': str(end - start), 'Content-Range': content_range, })
193+
response = self.s.post(upload_url, data=videoData[start:start + length])
194+
self.s.headers = headers
195+
196+
if response.status_code == 200:
197+
if self.configureVideo(upload_id, video, thumbnail, caption):
198+
self.expose()
139199
return False
140200

141201
def direct_share(self, media_id, recipients, text = None):
142202
# TODO Instagram.php 420-490
143203
return False
144204

145-
def configureVideo(self, upload_id, video, caption = ''):
146-
# TODO Instagram.php 490-530
147-
return False
205+
def configureVideo(self, upload_id, video, thumbnail, caption = ''):
206+
clip = VideoFileClip(video)
207+
self.uploadPhoto(photo=thumbnail, caption=caption, upload_id=upload_id)
208+
data = json.dumps({
209+
'upload_id': upload_id,
210+
'source_type': 3,
211+
'poster_frame_index': 0,
212+
'length': 0.00,
213+
'audio_muted': False,
214+
'filter_type': 0,
215+
'video_result': 'deprecated',
216+
'clips': {
217+
'length': clip.duration,
218+
'source_type': '3',
219+
'camera_position': 'back',
220+
},
221+
'extra': {
222+
'source_width': clip.size[0],
223+
'source_height': clip.size[1],
224+
},
225+
'device': self.DEVICE_SETTINTS,
226+
'_csrftoken': self.token,
227+
'_uuid': self.uuid,
228+
'_uid': self.username_id,
229+
'caption': caption,
230+
})
231+
return self.SendRequest('media/configure/?video=1', self.generateSignature(data))
148232

149233
def configure(self, upload_id, photo, caption = ''):
150234
(w,h) = getImageSize(photo)

0 commit comments

Comments
 (0)