56d5cd36 |
1 | import os |
2 | import sys |
3 | import time |
4 | |
5 | import json |
6 | import requests |
7 | from requests_oauthlib import OAuth1 |
8 | |
9 | |
10 | MEDIA_ENDPOINT_URL = 'https://upload.twitter.com/1.1/media/upload.json' |
11 | POST_TWEET_URL = 'https://api.twitter.com/1.1/statuses/update.json' |
12 | |
13 | CONSUMER_KEY = 'your-consumer-key' |
14 | CONSUMER_SECRET = 'your-consumer-secret' |
15 | ACCESS_TOKEN = 'your-access-token' |
16 | ACCESS_TOKEN_SECRET = 'your-access-secret' |
17 | |
18 | VIDEO_FILENAME = 'path/to/video/file' |
19 | |
20 | |
21 | oauth = OAuth1(CONSUMER_KEY, |
22 | client_secret=CONSUMER_SECRET, |
23 | resource_owner_key=ACCESS_TOKEN, |
24 | resource_owner_secret=ACCESS_TOKEN_SECRET) |
25 | |
26 | |
27 | class VideoTweet(object): |
28 | |
29 | def __init__(self, file_name): |
30 | ''' |
31 | Defines video tweet properties |
32 | ''' |
33 | self.video_filename = file_name |
34 | self.total_bytes = os.path.getsize(self.video_filename) |
35 | self.media_id = None |
36 | self.processing_info = None |
37 | |
38 | |
39 | def upload_init(self): |
40 | ''' |
41 | Initializes Upload |
42 | ''' |
43 | print('INIT') |
44 | |
45 | request_data = { |
46 | 'command': 'INIT', |
47 | 'media_type': 'video/mp4', |
48 | 'total_bytes': self.total_bytes, |
49 | 'media_category': 'tweetvideo' |
50 | } |
51 | |
52 | req = requests.post(url=MEDIA_ENDPOINT_URL, data=request_data, auth=oauth) |
53 | media_id = req.json()['media_id'] |
54 | |
55 | self.media_id = media_id |
56 | |
57 | print('Media ID: %s' % str(media_id)) |
58 | |
59 | |
60 | def upload_append(self): |
61 | ''' |
62 | Uploads media in chunks and appends to chunks uploaded |
63 | ''' |
64 | segment_id = 0 |
65 | bytes_sent = 0 |
66 | file = open(self.video_filename, 'rb') |
67 | |
68 | while bytes_sent < self.total_bytes: |
69 | chunk = file.read(4*1024*1024) |
70 | |
71 | print('APPEND') |
72 | |
73 | request_data = { |
74 | 'command': 'APPEND', |
75 | 'media_id': self.media_id, |
76 | 'segment_index': segment_id |
77 | } |
78 | |
79 | files = { |
80 | 'media':chunk |
81 | } |
82 | |
83 | req = requests.post(url=MEDIA_ENDPOINT_URL, data=request_data, files=files, auth=oauth) |
84 | |
85 | if req.status_code < 200 or req.status_code > 299: |
86 | print(req.status_code) |
87 | print(req.text) |
88 | sys.exit(0) |
89 | |
90 | segment_id = segment_id + 1 |
91 | bytes_sent = file.tell() |
92 | |
93 | print('%s of %s bytes uploaded' % (str(bytes_sent), str(self.total_bytes))) |
94 | |
95 | print('Upload chunks complete.') |
96 | |
97 | |
98 | def upload_finalize(self): |
99 | ''' |
100 | Finalizes uploads and starts video processing |
101 | ''' |
102 | print('FINALIZE') |
103 | |
104 | request_data = { |
105 | 'command': 'FINALIZE', |
106 | 'media_id': self.media_id |
107 | } |
108 | |
109 | req = requests.post(url=MEDIA_ENDPOINT_URL, data=request_data, auth=oauth) |
110 | print(req.json()) |
111 | |
112 | self.processing_info = req.json().get('processing_info', None) |
113 | self.check_status() |
114 | |
115 | |
116 | def check_status(self): |
117 | ''' |
118 | Checks video processing status |
119 | ''' |
120 | if self.processing_info is None: |
121 | return |
122 | |
123 | state = self.processing_info['state'] |
124 | |
125 | print('Media processing status is %s ' % state) |
126 | |
127 | if state == u'succeeded': |
128 | return |
129 | |
130 | if state == u'failed': |
131 | sys.exit(0) |
132 | |
133 | check_after_secs = self.processing_info['check_after_secs'] |
134 | |
135 | print('Checking after %s seconds' % str(check_after_secs)) |
136 | time.sleep(check_after_secs) |
137 | |
138 | print('STATUS') |
139 | |
140 | request_params = { |
141 | 'command': 'STATUS', |
142 | 'media_id': self.media_id |
143 | } |
144 | |
145 | req = requests.get(url=MEDIA_ENDPOINT_URL, params=request_params, auth=oauth) |
146 | |
147 | self.processing_info = req.json().get('processing_info', None) |
148 | self.check_status() |
149 | |
150 | |
151 | def tweet(self): |
152 | ''' |
153 | Publishes Tweet with attached video |
154 | ''' |
155 | request_data = { |
156 | 'status': 'I just uploaded a video with the @TwitterAPI.', |
157 | 'media_ids': self.media_id |
158 | } |
159 | |
160 | req = requests.post(url=POST_TWEET_URL, data=request_data, auth=oauth) |
161 | print(req.json()) |
162 | |
163 | |
164 | if __name__ == '__main__': |
165 | videoTweet = VideoTweet(VIDEO_FILENAME) |
166 | videoTweet.upload_init() |
167 | videoTweet.upload_append() |
168 | videoTweet.upload_finalize() |
169 | videoTweet.tweet() |