'Upload a media file to Twitter in multiple requests.
Args:
media:
File-like object to upload.
additional_owners: additional Twitter users that are allowed to use
The uploaded media. Should be a list of integers. Maximum
number of additional owners is capped at 100 by Twitter.
media_category:
Category with which to identify media upload. Only use with Ads
API & video files.
Returns:
media_id:
ID of the uploaded media returned by the Twitter API or 0.'

def UploadMediaChunked(self, media, additional_owners=None, media_category=None):

    url = ('%s/media/upload.json' % self.upload_url)
    (media_fp, filename, file_size, media_type) = parse_media_file(media)
    if (not all([media_fp, filename, file_size, media_type])):
        raise TwitterError({'message': 'Could    not    process    media    file'})
    parameters = {}
    if (additional_owners and (len(additional_owners) > 100)):
        raise TwitterError({'message': 'Maximum    of    100    additional    owners    may    be    specified    for    a    Media    object'})
    if additional_owners:
        parameters['additional_owners'] = additional_owners
    if media_category:
        parameters['media_category'] = media_category
    parameters['command'] = 'INIT'
    parameters['media_type'] = media_type
    parameters['total_bytes'] = file_size
    resp = self._RequestUrl(url, 'POST', data=parameters)
    data = self._ParseAndCheckTwitter(resp.content.decode('utf-8'))
    try:
        media_id = data['media_id']
    except KeyError:
        raise TwitterError({'message': 'Media    could    not    be    uploaded'})
    boundary = bytes('--{0}'.format(uuid4()), 'utf-8')
    media_id_bytes = bytes(str(media_id).encode('utf-8'))
    headers = {'Content-Type': 'multipart/form-data;    boundary={0}'.format(str(boundary[2:], 'utf-8'))}
    segment_id = 0
    while True:
        try:
            data = media_fp.read(self.chunk_size)
        except ValueError:
            break
        if (not data):
            break
        body = [boundary, 'Content-Disposition:    form-data;    name="command"', '', 'APPEND', boundary, 'Content-Disposition:    form-data;    name="media_id"', '', media_id_bytes, boundary, 'Content-Disposition:    form-data;    name="segment_index"', '', bytes(str(segment_id).encode('utf-8')), boundary, bytes('Content-Disposition:    form-data;    name="media";    filename="{0}"'.format(filename), 'utf-8'), 'Content-Type:    application/octet-stream', '', data, (boundary + '--')]
        body_data = '\r\n'.join(body)
        headers['Content-Length'] = str(len(body_data))
        resp = self._RequestChunkedUpload(url=url, headers=headers, data=body_data)
        if resp.content.decode('utf-8'):
            return self._ParseAndCheckTwitter(resp.content.decode('utf-8'))
        segment_id += 1
    try:
        media_fp.close()
    except:
        pass
    parameters = {'command': 'FINALIZE', 'media_id': media_id}
    resp = self._RequestUrl(url, 'POST', data=parameters)
    data = self._ParseAndCheckTwitter(resp.content.decode('utf-8'))
    try:
        return data['media_id']
    except KeyError:
        raise TwitterError({'message': 'Media    could    not    be    uploaded.'})
