YouTube API & JavaScript Upload
Создано Евгений Злобин в июня 26, 2010Задача: залить видео на ютуб при помощи браузера, html и JS и получить статус запроса и ID загруженного видео.
Никаких серверных технологий не используется. Only native JS.
Задача довольно не тривиальная. И поиск подобной реализации в сети не увенчался успехом. Создано по мотивам AJAX-транспорт Iframe, AjaxFileUpload и YouTube API. Основано на JQuery. Но при желании можно переделать под любой другой фреймворк или вообще без использования оных.
Отмечу, что скрипт уже должен иметь TOKEN и URL, о которых вы можете прочитать в API документации. В данном варианте скрипт разрабатывался для связки:
FLEX(TOKEN, URL)-JS-YOU_TUBE-JS(ID,STATUS)-FLEX
Для начала создадим форму в которой необходимо выбрать файл и нажать кнопку «Загрузить».
<form name="form" id="form-send" action="" method="POST" enctype="multipart/form-data">
<input type="hidden" name="yttoken" id="yttoken" value="">
<input type="hidden" name="yturl" id="yturl" value="">
<input id="fileToUpload" type="file" size="15" name="fileToUpload" class="input">
<button class="button" id="buttonUpload">Залить</button>
</form>
И создаём функцию, которая будет всё это дело обрабатывать.
function ajaxFileUpload(YT_TOKEN, YT_URL) {
$.ajaxFileUpload ({
url:YT_URL,
token:YT_TOKEN,
secureuri:false,
fileElementId:'fileToUpload',
dataType: 'json',
success: function (data, status) {
if ( typeof(data.error) != 'undefined' ) {
if ( data.error != '' ) {
alert(data.error);
} else {
alert(data.msg);
}
}
},
error: function (data, status, e) {
// myloc = УРЛ редиректа
myloc = myloc + '';
var get_pos = myloc.lastIndexOf("?");
myloc = myloc.substr(get_pos + 1);
var status_pos = myloc.lastIndexOf("status=");
var id_pos = myloc.lastIndexOf("id=");
var err_pos = myloc.lastIndexOf("error=");
ret_status = id_pos == -1 ?
myloc.substr(7,err_pos-8) : myloc.substr(7,id_pos-8);
ret_id = id_pos == -1 ?
myloc.substr(err_pos+6) : myloc.substr(id_pos+3);
alert(ret_status + ',' + ret_id);
}
}
)
return false;
}
Навешиваем на кнопку загрузки выполнение вышеприведённой функции
$('#buttonUpload').click(function() {
return ajaxFileUpload($('#yttoken').attr('value'),$('#yturl').attr('value'));
});
Суть работы скрипта такова – юзер выбирает файл на своём компьютере, затем нажимает кнопку «загрузить». И вызывается функция, приведенная выше. Которая выполняет следующие действия – создаётся iframe и форма при помощи которой мы будем отсылать данные на сервер YouTube
createUploadIframe: function(id, uri) {
var frameId = 'jUploadFrame' + id;
if ( window.ActiveXObject ) {
var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
if ( typeof uri== 'boolean' ){
io.src = 'javascript:false';
} else if ( typeof uri == 'string' ) {
io.src = uri;
}
} else {
var io = document.createElement('iframe');
io.id = frameId;
io.name = frameId;
}
io.style.position = 'absolute';
io.style.top = '-1000px';
io.style.left = '-1000px';
document.body.appendChild(io);
return io
},
createUploadForm: function(id, fileElementId, YT_URL, YT_TOKEN) {
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = $('<form action="' + YT_URL + '" method="POST" name="' + formId +
'" id="' + formId + '" enctype="multipart/form-data"> <input type="hidden"
name="token" value="' + YT_TOKEN + '"/></form>');
var oldElement = $('#' + fileElementId);
var newElement = $(oldElement).clone();
$(oldElement).attr('id', fileId);
$(oldElement).before(newElement);
$(oldElement).appendTo(form);
$(form).css('position', 'absolute');
$(form).css('top', '-1200px');
$(form).css('left', '-1200px');
$(form).appendTo('body');
return form;
},
Ну и соответственно функции, которые осуществляют Ajax транспорт и получают данные
ajaxFileUpload: function(s) {
s = jQuery.extend({}, jQuery.ajaxSettings, s);
var id = new Date().getTime()
var form = jQuery.createUploadForm(id, s.fileElementId, s.url, s.token);
var io = jQuery.createUploadIframe(id, s.secureuri);
var frameId = 'jUploadFrame' + id;
var formId = 'jUploadForm' + id;
if ( s.global && ! jQuery.active++ ) {
jQuery.event.trigger( "ajaxStart" );
}
var requestDone = false;
var xml = {}
if ( s.global )
jQuery.event.trigger("ajaxSend", [xml, s]);
// Ждём ответа
var uploadCallback = function(isTimeout) {
var io = document.getElementById(frameId);
try {
if( io.contentWindow ) {
xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
} else if ( io.contentDocument ) {
xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
}
} catch(e) {
myloc = window.frames[frameId].location;
jQuery.handleError(s, xml, null, e);
//alert('err1');
}
if ( xml || isTimeout == "timeout" ) {
requestDone = true;
var status;
try {
status = isTimeout != "timeout" ? "success" : "error";
if ( status != "error" ) {
var data = jQuery.uploadHttpData( xml, s.dataType );
if ( s.success )
s.success( data, status );
if( s.global )
jQuery.event.trigger( "ajaxSuccess", [xml, s] );
} else {
jQuery.handleError(s, xml, status);
}
} catch(e) {
status = "error";
myloc = window.frames[frameId].location;
//alert('err3');
jQuery.handleError(s, xml, status, e);
}
// Запрос завершен
if( s.global ) {
jQuery.event.trigger( "ajaxComplete", [xml, s] );
}
if ( s.global && ! --jQuery.active ) {
jQuery.event.trigger( "ajaxStop" );
}
// результаты
if ( s.complete ) {
s.complete(xml, status);
}
jQuery(io).unbind()
setTimeout(function(){
try {
$(io).remove();
$(form).remove();
} catch(e) {
myloc = window.frames[frameId].location;
jQuery.handleError(s, xml, null, e);
//alert('err4');
}
}, 100)
xml = null
}}
if ( s.timeout > 0 ) {
setTimeout(function(){
if( !requestDone ) uploadCallback( "timeout" );
}, s.timeout);
}
try {
// var io = $('#' + frameId);
var form = $('#' + formId);
$(form).attr('action', s.url);
$(form).attr('method', 'POST');
$(form).attr('target', frameId);
if ( form.encoding ) {
form.encoding = 'multipart/form-data';
} else {
form.enctype = 'multipart/form-data';
}
$(form).submit();
} catch(e) {
jQuery.handleError(s, xml, null, e);
}
if ( window.attachEvent ) {
document.getElementById(frameId).attachEvent('onload', uploadCallback);
} else {
document.getElementById(frameId).addEventListener('load', uploadCallback, false);
}
return {abort: function (){}};
},
uploadHttpData: function( r, type ) {
var data = !type;
data = type == "xml" || data ? r.responseXML : r.responseText;
if ( type == "script" )
jQuery.globalEval( data );
if ( type == "json" )
eval( "data = " + data );
if ( type == "html" )
jQuery("<div>").html(data).evalScripts();
//alert($('param', data).each(function(){alert($(this).attr('value'));}));
return data;
}
В итоге двое суток работы и задача решена
Ну и прикрепляю исходные коды скрипта. Скачать


Неплохо придумано и главное полезно, пригодится. Я думаю оценят по достоинству.
Жесть. Учусь потихоньку программированию. Но пока для меня это сложно.
Незнаю полезно ли, хотя для кого как…мне дак оно вообще не нужно
Да, наворочено…. но надо пробовать, а-то у других есть и мне охота…
Спасибо большое. Мне очень помогло. А то я долго мучался!!!
Конечно круто, но слишком грузно моно и по проще сделать
Работа неплохая. Только где использовать данный скрипт не сильно понятно.
Огромное спасибо за данный скриптик, какраз пригодится для нового сайта!
Только начал изучать но я не сказал бы что это легко.
Полезно однозначно. А если кому бесполезно – так для общего развития пригодиться, а то рискуем в рядовых потребителей деградировать, на радость буржуям.
Спасибо за полезный скрипт. нужно будет использовать для своих видео файлов.
lyrics, да слижком уж это узко специализированно. Просто нам понадобилась такая реализация для одного из виджетов на Flex.
Небезопасно все это…
Зафига открытый код выкладывать?
полезно, очень даже.
Очень круто. Вопрос рождается сам с собой- «Зачем??» Если есть по дефолту такая функция на ютубе?! Или это просто фичя на хостинг?
Создатель достоин одного слова СПАСИБО !!!
SpauN, это было написано для одного нашего сайта.
создатель наверно гений, или просто знает свою работу! чтобы такой скрипт написать нужна голова, кароче спасибо
голова нужна оОООо!
столько «спасибо».. только я ума не приложу, это чтобы грузить видео на трубу через свой сайт? :/
Вроде нормуль,но сильно грузит….
Мб попроще сделаю,на досуге
Тем не менее постоянно у них испытываю проблемы с заливкой видео
Спасибо скрипт очень полезный и мне очень помог, не всегда удобно грузить по дефолту как уже было сказано, а с помощью скрипта очень удобно!
Что-то не работает, передаю токен через google AuthSubRequest. После закачки выдает только алерт с именем домена.
Geby, ну а само видео то вообще закачивается? Тут есть ещё один подводный камень, о котором я узнал уже позже. Нужно, чтобы этот скрипт обязательно выполнять на каком-либо сервере, т.е. если запускаете со своего компа, то нужно запускать, например с http://localhost/ Видимо это как-то связано с получением HTTP_REFERER
Запускал сразу на хосте. Возможео неверно оформляю запрос. Может есть рабочий пример?
Я считаю полезно, ну как по мне так пригодилось
Кто-нибудь пробовал адаптировать его под blip.tv? а то на ютубе ограничения по размеру/времени..
Geby, напишите мне в скайп creastar-group
интересный код. спасибо
Про Zend_Gdata слыхали? Уже все давно написано
http://code.google.com/intl/en/apis/youtube/2.0/developers_guide_php.html
вообще-то вы описываете серверную часть. У меня идет описание работы без оной.
Отлично, надо будет использовать где-то.
Есть ли какие то варианты отображения здесь progress bar, процента загрузки видео?
Дмитрий, видел что в браузере это отображается, но вот возможно ли это как-то перехватить даже не знаю.
Эта штука не работает в опере?