I've been stuck on this issue for awhile and i can't seem to find a solution. What i am trying to achieve is this:
Select a video from the phone's library
Upload the video to Amazon AWS using a signed PUT url
Download the uploaded video and play it back on the PC
I am able to select the video from the phone's gallery and successfully upload it to Amazon aws. However, when i try to open and playback the file, media player says that the file format is not supported.
It cannot be a codec issue with my player because i can playback other videos that were uploaded to amazon (via standard HTML file input). Plus, when i transfer the same video from my phone to the desktop, it is playable.
I have a feeling that i'm missing out something when setting up the FileTransfer object. Below is a snippet of my code:
navigator.camera.getPicture(
function(imgUrl) {
that.mDialogOpen("Uploading video...");
window.resolveLocalFileSystemURL(imgUrl, function(fileEntry) {
fileEntry.file(function(file) {
var parts = fileEntry.nativeURL.split('/');
var filename = parts[parts.length - 1];
// Params is sent to the server to generate the signed amazon put url
var params = {'a':'handlerFunctionKey', 'name':filename, 'type':'multipart/encrypted'};
var callback = function(data) {
alert("In callback");
var dataResp = data['handlerFunctionKey'];
if (dataResp.status == 'SUCCESS') {
var amazonUrl = decodeURIComponent(dataResp.object);
alert("Setting up options: " + file.type);
var ftOptions = new FileUploadOptions();
ftOptions.fileName = filename;
ftOptions.mimeType = file.type;
ftOptions.chunkedMode = false;
ftOptions.headers = {'Content-Type':"multipart/encrypted",'x-amz-acl':'public-read',"Connection":"close"};
ftOptions.httpMethod = 'PUT';
var ft = new FileTransfer();
ft.upload(imgUrl, amazonUrl,
function() {
$("#mModalText").html("Upload success");
},
function(err) {
alert("Upload error: " + err.code);
alert("Upload target: " + err.target);
alert("Upload source: " + err.source);
}, ftOptions, true);
}
};
that.doAjax(params, callback); // Execute ajax call to server and run the callback function upon response
}, function() {});
}, function() {});
},
function() {}, options);
The 'options' for the getPicture function are:
var options = {quality:50, destinationType:Camera.DestinationType.FILE_URI};
options['sourceType'] = Camera.PictureSourceType.PHOTOLIBRARY;
options['mediaType'] = Camera.MediaType.VIDEO;
options['targetWidth'] = 640;
options['targetHeight'] = 480;
The video i'm uploading is a MP4 with mimeType 'video/mp4'. I'm testing this on an Android. I'm building the code with Phonegap version 6.0.1 via remote build.
Thanks in advance.
Related
i am trying to download images from s3 server using cordova-plugin-file-transfer
my code works with other images from google or diffrent servers.
but when i tried to download from s3 it shows error.
downloadimg ="https://s3.amazonaws.com/bucket/img/5.jpg";
var fileTransfer = new FileTransfer();
var uri = encodeURI(downloadimg);
var package_root = cordova.file.externalRootDirectory + ".appname";
var imgindex = downloadimg.lastIndexOf("/") + 1;
var imgname = downloadimg.substr(imgindex);
var fileURL = package_root + imgname;
console.log(uri);
console.log(fileURL);
fileTransfer.download(
uri,
fileURL,
function (entry) {
console.log("success");
},
function (error) {
console.dir(error);
},
false,
{
headers: {
"Authorization": "Basic dGVzdHVzZXJuYW1lOnRlc3RwYXNzd29yZA=="
}
}
);
i tried adding {encodeURI:false}; and 'Content-type':'image/jpg' in option header but did not work.
Try this:
Enable CORS configuration.
Remove header auth
Check buckets policy (you can test making the object public)
Hope to help you.
I'm using the following code to record audio using Cordova Media plugin on android devices. This results in an empty audio file despite returning successfully on stopRecord(). Can somebody point to what might be wrong with this code?
$cordovaFile.createFile(cordova.file.dataDirectory, 'new-rec.amr'), false)
.then(function (fileObj) {
console.log('File created', fileObj);
var nativePath = fileObj.nativeURL;
resolveLocalFileSystemURL(nativePath, function (entry) {
var internalPath = entry.toInternalURL();
var mediaRec = new Media(internalPath,
//success callback
function (success) {
console.log("record success", success);
},
//error callback
function (err) {
console.log("record error: " + JSON.stringify(err));
});
// Start recording audio
mediaRec.startRecord();
});
}, function (error) {
console.log('Cannot create a file to initiate a new recording', error);
});
I was having this exact same problem today. Solved it by releasing the Media object. I'm not sure why this helped, but I have a feeling it may be that the OS is holding onto the Media object instead of saving it and then once it's released it's properly saved?
Not 100% sure though. It works without releasing in other Cordova directories (e.g. cordova.file.externalDataDirectory).
Here's my code:
var fileName = randomFileName();
fileName = fileName + ".aac";
var store = cordova.file.dataDirectory;
window.resolveLocalFileSystemURL(store, function(dir){
var directoryToSave = dir.nativeURL + fileName;
$scope.audioRecording = new Media(directoryToSave, audioRecordingSuccess, audioRecordingFail, audioStatus);
$scope.audioRecording.startRecord();
setTimeout(function(){
$scope.audioRecording.stopRecord();
$scope.audioRecording.release();
}, 5000);
});
I'm developing a mobile app for iOS and Android using Cordova and Ionic Framework. There needs to be 'Send Photo' and related functionality, and I'm using Cordova's FileTransfer to do this.
It works perfectly on iOS simulator, but throws "error code = 1" on Android device.
I know this means file_not_found or similar.
Note it happens if I take a picture from camera, or choose one from gallery.
Here is my code:
$scope.takePic = function() {
var options = {
quality: 50,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: 0, // 0:Photo Library, 1=Camera, 2=Saved Photo Album
encodingType: 0 // 0=JPG 1=PNG
}
navigator.camera.getPicture(onSuccess, onFail, options);
}
var onSuccess = function(FILE_URI) {
window.resolveLocalFileSystemURL(FILE_URI, function(fileEntry) {
alert("full: " + JSON.stringify(fileEntry));
var realUrl = fileEntry.toURL();
$scope.picData = realUrl;
$scope.$apply();
console.log("real URL", realUrl);
});
};
var onFail = function(e) {
console.log("On fail " + e);
}
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
Flash.success("Wysłano");
var response = JSON.parse(r.response);
$scope.attachment_id = response.data;
$scope.$apply();
$http.post($rootScope.baseServerUrl + 'Members/changeAvatar', {attachment_id: response.data}).success( function (response){
console.log(response);
});
}
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
$scope.send = function() {
Flash.warning('wysyłam');
var myImg = $scope.picData;
alert(myImg);
var options = new FileUploadOptions();
options.headers = {
Accept: "application/json",
Connection: "close"
}
options.fileKey="file";
options.fileName=$scope.picData.substr($scope.picData.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload(myImg, encodeURI($rootScope.baseServerUrl + 'media/Attachments/add'), win, fail, options);
}
$scope.takePic and send are called by button clicks. There are a lot of alerts and console because I'm trying to find why its not working.
After picking a picture from the gallery on android I get:
file:///storage/sdcard0/download/file-name.jpg
on iOS simulator:
file:///Users//Library/Application%20Support/iPhone%20Simulator/7.1/Applications/B5FB2081-54E7-4335-8856-84C6499E6B07/tmp/cdv_photo_038.jpg
and by using this path I can show this picture by using <img src="{{picData}}"> this works on both platforms.
But if I try to send it on an Android device I get error Code = 1. On iOS sim it sends, photo, gets proper response, changes avatar...everything.
Both Cordova and plugins File and FileTransfer are up to date.
It looks like you might have a path error, file:///storage.sdcard0/download/file-name.jpg should be file:///storage/sdcard0/download/file-name.jpg if I'm not mistaken.
From perusing your code, it doesn't appear that you are parsing anything incorrectly. Maybe you want to try using an older more stable version of the file plugin if it is returning the wrong URI (and maybe file a bug report)? I haven't used the file plugin since they released 1.0, but from personal experience there have been bugs/regressions in the bleeding edge releases before.
You can target specific plugin versions from the cordova-cli using # like cordova plugin add org.apache.cordova.file#1.0.0
As well as specific tags/releases from github using # like cordova plugin add https://github.com/apache/cordova-plugin-file-transfer#r0.4.2
Maybe late but I've kinda fixed it.
In my view file I use:
<input id="file" name="file" type="file" onchange="angular.element(this).scope().addFile(this)" class="upload" accept="image/*" capture="camera"/>
so it fires $scope.addFile() from my controller as soon as you pick up file from galery:
$scope.addFile = function(item){
function uploadComplete(evt) {
/* This event is raised when the server send back a response */
$scope.imgId = JSON.parse(evt.target.responseText).data;
$scope.$apply();
$http.post($rootScope.baseServerUrl + 'Members/changeAvatar', {attachment_id: $scope.imgId}).success( function (response){
console.log(response);
$scope.User.attachment_id = $scope.imgId;
$scope.$apply();
});
}
function uploadFailed(evt) {
alert("There was an error attempting to upload the file.")
};
var updateImage = function (element) {
$scope.$apply(function() {
$scope.theFile = element.files[0];
var formData = new FormData();
formData.append("file", $scope.theFile);
var xhr = new XMLHttpRequest()
xhr.addEventListener("load", uploadComplete, false)
xhr.addEventListener("error", uploadFailed, false)
xhr.open("POST", $scope.baseServerUrl + "media/Attachments/add")
xhr.setRequestHeader("Accept","application/json")
$scope.progressVisible = true
xhr.send(formData);
});
};
updateImage(item)
}
Works for all Android devices I tested, above 4.0 excluding 4.4 because of input type="file" bug, works on iOS simulator and devices with 8.1 system (should also on older but I didn't test it).
It's not a perfect solution, because you can use only pictures you already got on your phone. I couldnt figure it out how to use Cordova FileTransfer with our server authentication way: I was always getting "please log in" in response, even when I tried adding all needed headers, tokens, anything...
So even though this solution is far from what I wanted to achieve - it works. Hope it helps anyone.
I have implemented a app for android using phone Gap.
In the app I have two button one is Voice Enroll and another one is Voice Verification.
For Voice Enroll I implemented Record Function Using CaptureAudio in Phone Gap. It works Great.
Now I need to upload the Record file to server. I have Used Below Code.
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
alert(mediaFiles[i]);
uploadFile(mediaFiles[i]);
}
}
function captureError(error) {
var msg = 'An error occurred during capture: ' + error.code;
navigator.notification.alert(msg, null, 'Uh oh!');
}
function captureAudio() {
navigator.device.capture.captureAudio(captureSuccess, captureError, {limit: 3);
}
// Upload files to server
function uploadFile(mediaFile) {
var ft = new FileTransfer(),
recordingPath = mediaFile.fullPath,
name = mediaFile.name;
console.log('Path is: ' + recordingPath);
ft.upload(recordingPath,
"Webservice URL",
function(result) {
alert("Hi");
console.log('Upload success: ' + result.responseCode);
console.log(result.bytesSent + ' bytes sent');
},
function(error) {
alert("welcome");
console.log('Error uploading file ' + recordingPath + ': ' + error.code);
},
{ fileName: name });
alert(recordingPath);
}
When I alert that mediaFiles[i] is received "Object Object". I can't receive any response after uploading.
Once Success we receive some messages from server about the audio file.
I am also send the audio file name as 'utterence'. How can i done this using phonegap and jquery mobile?
I remember having a similar problem and in my case the problem was capture returned full path and upload required the file path in different format so I had to modify the full path in a format accepted by upload.
Also make sure you set mimeType in the upload function. It defaults to image/jpeg. I am not sure how your server behaves but if it has self signed certificates then you will have to set trustAllHosts to true.
Hope this helps
I'm able to upload an image using the the camera, but I can't seem to get the correct file name to upload (error code 1 NOT_FOUND_ERR) when trying to upload a file from my app. What I'm trying to do is upload a default profile image to server when a user first signs up.
Here is my code, which is almost identical to the working camera upload I have:
// Source
path = 'images/default.jpeg';
// Destination
var url = 'http://serverloc/data';
// Upload Options
var options = new FileUploadOptions();
options.fileKey = 'file';
options.fileName = path.substr(path.lastIndexOf('/') + 1);
options.mimeType = 'image/jpeg';
options.chunkedMode = false;
var params = new Object();
params.fullpath = path;
params.name = options.fileName;
options.params = params;
// Upload
var ft = new FileTransfer();
ft.upload(path, url,
function(result) {
// hasn't worked yet
},
function(error) {
alert('Error uploading default image: ' + error.code);
// 1 - NOT_FOUND_ERR
},
options);
Testing on Android.
Update: Since I can't this working, I guess my next best option is to add a marker property for each user, and if that propery (default-img say) is "yes", then I'll display the default image in-app, rather than having it stored on the server.