#python #django #youtube
#python #django #YouTube
Вопрос:
Я могу загружать видео на YouTube через свое приложение Django, но только тогда, когда они загружены с моего ноутбука. YouTube выдает мне ошибку «Обработка прервана», когда я загружаю одно и то же видео через свой iPhone.
Я запускаю Ubuntu 16.04.3 с версией Django 1.11.20 и Python 2.7. Я использую функцию в своих представлениях для получения загруженного файла и, если он превышает 2,5 мегабайта, извлекаю файл из каталога / tmp, а если он меньше 2,5 мегабайт, обрабатываю файл из памяти.
Это работает, когда я загружаю видеофайлы со своего ноутбука, но не работает, когда я загружаю видеофайлы со своего iPhone.
Чтобы было понятно, я не получаю ошибок от Django / Python. Файл, похоже, загружается, обрабатывается и удаляется просто отлично. Но после того, как YouTube получает его, я захожу в свою студию YouTube, и она выдает мне «Обработка прекращена. Это видео не удалось обработать», ошибка.
def upload_to_youtube(request):
if request.method == 'POST' and request.FILES['video']:
video_file = request.FILES['video']
if video_file.size >= 2621440:
fname = request.FILES['video'].file.name
storage = DjangoORMStorage(CredentialsModel, 'id', request.user.id, 'credential')
credentials = storage.get()
client = build('youtube', 'v3', credentials=credentials)
body = {...}
with tempfile.NamedTemporaryFile('wb', suffix='yt-django') as tmpfile:
with open(fname, 'rb') as fileobj:
tmpfile.write(fileobj.read())
insert_request = client.videos().insert(
part=','.join(body.keys()),
body=body,
media_body=MediaFileUpload(
tmpfile.name, chunksize=-1, resumable=True)
)
insert_request.execute()
else:
storage = DjangoORMStorage(CredentialsModel, 'id', request.user.id, 'credential')
credentials = storage.get()
client = build('youtube', 'v3', credentials=credentials)
body = {...}
with tempfile.NamedTemporaryFile('wb', suffix='yt-django') as tmpfile:
tmpfile.write(request.FILES['video'].read())
insert_request = client.videos().insert(
part=','.join(body.keys()),
body=body,
media_body=MediaFileUpload(
tmpfile.name, chunksize=-1, resumable=True)
)
insert_request.execute()
Первоначально думая, что это связано с размером файла, я написал в чеке, чтобы обработать файл по-другому, если он был 2,5 МБ или меньше, вместо этого обработать его из памяти. Однако даже с файлом размером менее 2,5 Мб, отправленным с ноутбука, он все равно будет загружаться просто отлично. Я не уверен, есть ли что-то в моем коде Django / Python, что вызывает проблемы при загрузке на iOS, или это находится в конце YouTube.
Ответ №1:
Хорошо, похоже, я понял это. Следуя заметкам разработчика YouTube, я переместил фактическую загрузку видео со своего сервера на YouTube в его собственную функцию, которая выдала бы мне любые ошибки, которые у нее были. Я не получил никаких ошибок, но с тех пор это работает. Вот новый код:
if request.method == 'POST' and request.FILES['video']:
video_file = request.FILES['video']
if video_file.size >= 2621440:
fname = request.FILES['video'].file.name
messages.success(request, "Equal to or over 2.5 megabytes, saving to disk and uploading")
storage = DjangoORMStorage(CredentialsModel, 'id', request.user.id, 'credential')
credentials = storage.get()
client = build('youtube', 'v3', credentials=credentials)
body = {
'snippet': {
'title': 'Upload Youtube Video',
'description': 'Video Description',
'tags': 'django,howto,video,api',
'categoryId': '27'
},
'status': {
'privacyStatus': 'unlisted'
}
}
with tempfile.NamedTemporaryFile('wb', suffix='yt-django') as tmpfile:
with open(fname, 'rb') as fileobj:
tmpfile.write(fileobj.read())
insert_request = client.videos().insert(
part=','.join(body.keys()),
body=body,
media_body=MediaFileUpload(
tmpfile.name, chunksize=-1, resumable=True)
)
resumable_upload(insert_request)
else:
messages.success(request, "Under 2.5 megabytes, uploading from memory")
storage = DjangoORMStorage(CredentialsModel, 'id', request.user.id, 'credential')
credentials = storage.get()
client = build('youtube', 'v3', credentials=credentials)
body = {
'snippet': {
'title': 'Upload Youtube Video',
'description': 'Video Description',
'tags': 'django,howto,video,api',
'categoryId': '27'
},
'status': {
'privacyStatus': 'unlisted'
}
}
with tempfile.NamedTemporaryFile('wb', suffix='yt-django') as tmpfile:
tmpfile.write(request.FILES['video'].read())
insert_request = client.videos().insert(
part=','.join(body.keys()),
body=body,
media_body=MediaFileUpload(
tmpfile.name, chunksize=-1, resumable=True)
)
resumable_upload(insert_request)
def resumable_upload(request):
httplib2.RETRIES = 1
MAX_RETRIES = 10
RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, httplib.NotConnected, httplib.IncompleteRead,
httplib.ImproperConnectionState, httplib.CannotSendRequest, httplib.CannotSendHeader, httplib.ResponseNotReady,
httplib.BadStatusLine)
RETRIABLE_STATUS_CODES = [500, 502, 503, 504]
response = None
error = None
retry = 0
while response is None:
try:
print 'Uploading file...'
status, response = request.next_chunk()
if response is not None:
if 'id' in response:
print 'Video id "%s" was successfully uploaded.' % response['id']
else:
exit('The upload failed with an unexpected response: %s' % response)
except HTTPError, e:
if e.resp.status in RETRIABLE_STATUS_CODES:
error = 'A retriable HTTP error %d occurred:n%s' % (e.resp.status, e.content)
else:
raise
except RETRIABLE_EXCEPTIONS, e:
error = 'A retriable error occurred: %s' % e
if error is not None:
print error
retry = 1
if retry > MAX_RETRIES:
exit('No longer attempting to retry.')
max_sleep = 2 ** retry
sleep_seconds = random.random() * max_sleep
print 'Sleeping %f seconds and then retrying...' % sleep_seconds
time.sleep(sleep_seconds)