Upload video file to firebase storage


#1

I have followed this video : https://www.youtube.com/watch?v=6yGrLWq-oIo
and I can successfully pick the image from library from changeing sourceType: Camera.PictureSourceType.CAMERA to Camera.PictureSourceType.PHOTOLIBRARY of the cordova plugin-camera.

Instead of uploading images, may I know how to choose video files and upload to firebase for ionic2?

Many thanks.


#2

First off thanks for watching the video!!

you should be able to just select a video object and upload the blob the same was as uploading the image object.

cordova plugin add cordova-plugin-media-capture

https://www.npmjs.com/package/cordova-plugin-media-capture


#3

I haven’t tried cordova-plugin-media-capture, but I found the cordoba-plugin-camera can select the type of media, I have added : mediaType : Camera.MediaType.ALLMEDIA, applying into your tutorial
Reference : https://github.com/apache/cordova-plugin-camera

Then, I can access to the video library, I got the video path like capturing image as your tutorial, like this:
got image path /storage/external_SD/DCIM/Camera/20160903_12034.mp4

But it can’t jump to the next step, makeFIleIntoBlob, I think it may be related to the type:
var reader = new FileReader(); reader.onloadend = (evt: any) => { var imgBlob: any = new Blob([evt.target.result], { type: 'image/jpeg' }); imgBlob.name = 'sample.jpg'; resolve(imgBlob); };

May I know do you have any suggestions? Many thanks.
P.S. I am testing in Android device.


#4

I am facing exactly same issue


#5

post some code? I will take a look


#6

console.log(‘taking pic’);

Camera.getPicture({
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
targetWidth: 640,
correctOrientation: true
}).then((imageData) => {

imageData = “file://” + imageData

console.log(imageData);

window.resolveLocalFileSystemURL(imageData, (fileEntry) => {

console.log(fileEntry);

fileEntry.file((resfile)=>{

console.log(resfile);

var reader = new FileReader();
reader.onloadend = (evt: any) => {
var imgBlob: any = new Blob([evt.target.result], { type: ‘image/jpeg’ });
imgBlob.name = ‘sample.jpg’;

console.log(‘blob created0’);

this.firebase.uploadPhotoFromFile(imgBlob,(snapshot)=>{

console.log(snapshot);

});

}

})

})

})

}

In the above code , everything within onloadend never gets called , and I dont get any error.Can anyone help with this?
Thanks


#7

try using FileReader.onload not FileReader.onloadend


#8

Tried that , I can confirm its not working


#9

Hey guys, I got something working, so I thought I would share what I did. Given that this might not work for all cases, but it should be able to get you started.

First, I start the process off in a service I call CameraService (now called providers). This is a fully functional version, so there is a significant amount of side cases I handle here.

import { Injectable } from '@angular/core'; import { Platform } from 'ionic-angular'; import { Camera } from 'ionic-native'; import { StorageService } from './storage.service'; import { AuthService } from './auth.service'; declare var window: any; @Injectable() export class CameraService {
// Ability to upload videos
public options: any = {
      sourceType: Camera.PictureSourceType.SAVEDPHOTOALBUM,
      mediaType: Camera.MediaType.ALLMEDIA,
      destinationType: Camera.DestinationType.FILE_URI
}

constructor(public platform: Platform,
            public storage: StorageService,
            public auth: AuthService) {}

getMedia(): Promise<any> {
  return new Promise((resolve, reject) => {
    Camera.getPicture(this.options).then( (fileUri: any) => {
      console.log('File URI: ' + JSON.stringify(fileUri));
      window.resolveLocalFileSystemURL('file://' + fileUri, (fileEntry) => {
        console.log('Type: ' + (typeof fileEntry));
         fileEntry.file( (file) => {
           console.log('File: ' + (typeof file) + ', ' + JSON.stringify(file));
           const fileReader = new FileReader();
           
           fileReader.onloadend = (result: any) => {
             console.log('File Reader Result: ' + JSON.stringify(result));
             let arrayBuffer = result.target.result;
             let blob = new Blob([new Uint8Array(arrayBuffer)], {type: 'video/mp4'});
             const name = '' + Date.now() + this.auth.id;
             this.upload(blob, name , file.type, resolve, reject);
           };

           fileReader.onerror = (error: any) => {
             reject(error);
           };
           
           fileReader.readAsArrayBuffer(file);
         }, (error) => {
           console.log('File Entry Error: ' + JSON.stringify(error));
         });
      }, (error) => {
        console.log('Error resolving file: ' + JSON.stringify(error));
      });
    });
  });
}

upload(blob: Blob, name: string, type: string, resolve: any, reject: any) {
let uploadTask = this.storage.addBlob( name , type, blob);
     uploadTask.on('state_changed' , (snapshot) => {
        // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
        var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
        console.log('Upload is ' + progress + '% done');
        switch (snapshot.state) {
          case firebase.storage.TaskState.PAUSED: // or 'paused'
            console.log('Upload is paused');
            break;
          case firebase.storage.TaskState.RUNNING: // or 'running'
            console.log('Upload is running');
            break;
        }
      }, (error: any) => {
        console.log('An Error has occured');
        switch (error.code) {
          case 'storage/unauthorized':
            // User doesn't have permission to access the object
            console.log('Unauthorized Access: ' + JSON.stringify(error));
            reject(error.code);
            break;
          case 'storage/canceled':
            // User canceled the upload
            console.log('Canceled');
            reject(error.code);
            break;
          case 'storage/unknown':
            // Unknown error occurred, inspect error.serverResponse
            console.log('Storage Unkown: ' + JSON.stringify(error));
            reject(error.code);
            break;
          default:
            console.log('Default: ' + JSON.stringify(error));
            reject(error.code);
            break;
        }
      }, () => {
        console.log('Finished Uploading');
        resolve( {url: uploadTask.snapshot.downloadURL, name: name, mediaType: type} );
      });
  }
}

This allows me to return a promise, and I should walk threw a lot of this code as it gets pretty complicated. First, I use non-native’s camera plugin and their getPicture method. this will return me with a file URI, which on android looks something like

/storage/emulated/0/Movies/Instagram/VID_20880804_030651.mp4

Then, I need to convert this into a FileEntry object. Refer to Mozilla’s FileEntry object. To do this I need the function listed above

window.resolveLocalFileSystemURL( url , function() )

If you noticed I had to add file:// to the URL I got earlier, that was android specific, and I haven’t fully tested this on IOS. Then I need a file entry file, which unfortunately for me does not convert the object into a javascript file object (or else I could use firebase’s storage to automatically put it up). Instead, I need to use FileReader to read the object into memory, and then on completion, create a Blob to upload to firebase.

The last and most important line of code here was

this.upload(blob, name, type)

But that just references another service that does a native firebase call

firebase.storage().ref().child('videos').child(name).put(blob)

That returns an URL, which I use in my promise resolution.

I know this is quite complicated, so feel free to ask questions. Thought I would share and help anyone out that I could.

Edit: Be sure to add the cordova file plugin to your app. Without this, the window.resolvelocalfilesystemURL call will probably fail.


#10

I have just gone through and created a demo app doing the same thing but with Kinvey… I follow the same approach for getting the file from the camera that can be used with Firebase