Appcelerator: Как загрузить видео с помощью Android?

Я получил Iphone/ Ipad, чтобы нормально работать с функцией Titanium.Media.showCamera(). Что здорово.

Однако тот же код не работает на Android, как я ожидаю. Поэтому я провел небольшое исследование и придумал этот код ниже. Сам код работает до загрузки видео. Я могу записать, нажать "Сохранить", но когда приходит время загрузки на мой сервер, я не получаю сообщение об ошибке связи, и на самом сервере я не вижу данных в массиве POST или FILES. Код ниже выполняется на кнопке onclick. Я даю часть кода, так как все работает, кроме этого. Что дает?

button2.addEventListener('click', function() {
    // http://developer.android.com/reference/android/provider/MediaStore.html
    var intent = Titanium.Android.createIntent({ action: 'android.media.action.VIDEO_CAPTURE' });
    Titanium.Android.currentActivity.startActivityForResult(intent, function(e) {
        if (e.error) {
            Ti.UI.createNotification({
                duration: Ti.UI.NOTIFICATION_DURATION_LONG,
                message: 'Error: ' + e.error
            }).show();
        } else {
            if (e.resultCode === Titanium.Android.RESULT_OK) {
                var dataUri = e.intent.data;

                Titanium.Media.saveToPhotoGallery(dataUri);


                var xhr = Titanium.Network.createHTTPClient({enableKeepAlive:false});
                xhr.open('POST', 'http://someserver.com/upload.php');
                xhr.setRequestHeader("enctype", "multipart/form-data");
                xhr.setRequestHeader('Cache-Control', 'no-cache');
                xhr.onerror = function(e) {
                    alert(e.error);
                };
                xhr.onload = function() {
                    var data = JSON.parse(this.responseText);
                    if(data.FILE)
                        alert('File: '+data.FILE);
                    else
                        alert(this.responseText);
                };

                var fileData = Titanium.Filesystem.getFile(dataUri);
                var fileContent = fileData.read();
                xhr.send({video: fileContent});
            } else {
                Ti.UI.createNotification({
                    duration: Ti.UI.NOTIFICATION_DURATION_LONG,
                    message: 'Canceled/Error? Result code: ' + e.resultCode
                }).show();
            }
        }
    });
});

Также, если вас интересует код php, вот он:

<?php

file_put_contents('output.txt', print_r($_POST, true)."\n".print_r($_FILES, true));

if(empty($_FILES['video']))
        die('invalid');

@move_uploaded_file($_FILES['video']['tmp_name'], $_FILES['video']['name']);
echo json_encode(array('FILE' => $_FILES['video']['name']));

1 ответ

Решение

Ладно разобрался. Проблема в том, что файл является URI, а код не читает URI в файловой системе. С учетом сказанного вам придется скопировать файл в новый файл, а затем использовать этот новый файл для загрузки на сервер.

Решение ниже работает для меня:

button2.addEventListener('click', function() {
    // http://developer.android.com/reference/android/provider/MediaStore.html
    var intent = Titanium.Android.createIntent({ action: 'android.media.action.VIDEO_CAPTURE' });
    Titanium.Android.currentActivity.startActivityForResult(intent, function(e) {
        if (e.error) {
            Ti.UI.createNotification({
                duration: Ti.UI.NOTIFICATION_DURATION_LONG,
                message: 'Error: ' + e.error
            }).show();
        } else {
            if (e.resultCode === Titanium.Android.RESULT_OK) {
                var dataUri = e.intent.data;




                var xhr = Titanium.Network.createHTTPClient({enableKeepAlive:false});
                xhr.open('POST', 'http://something.com/video/uploader.php');
                xhr.setRequestHeader("enctype", "multipart/form-data");
                xhr.setRequestHeader('Cache-Control', 'no-cache');
                xhr.onerror = function(e) {
                    alert(e.error);
                };
                xhr.onload = function() {
                    var data = JSON.parse(this.responseText);
                    if(data.FILE)
                        alert('File: '+data.FILE);
                    else
                        alert(this.responseText);
                };

                var source = Ti.Filesystem.getFile(dataUri);
                var fileData = Ti.Filesystem.getFile('appdata://sample.3gp');
                // note: source.exists() will return false, because this is a URI into the MediaStore.
                // BUT we can still call "copy" to save the data to an actual file
                source.copy(fileData.nativePath);
                Titanium.Media.saveToPhotoGallery(fileData);
                if(fileData.exists())
                {
                    var fileContent = fileData.read();
                    if(fileContent)
                        xhr.send({video: fileContent});
                    else
                        alert('Did not get any data back from file content');
                }
                else
                    alert('Did not get a file data for : '+dataUri);
            } else {
                Ti.UI.createNotification({
                    duration: Ti.UI.NOTIFICATION_DURATION_LONG,
                    message: 'Canceled/Error? Result code: ' + e.resultCode
                }).show();
            }
        }
    });
});
Другие вопросы по тегам