Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uploading video to Google Drive programmatically (Android API)

I have followed the Drive API guide (https://developer.android.com/google/play-services/drive.html) and my app now uploads photos smoothly, but I am now trying to upload videos (mp4) without success.

Does anyone know how to achieve this? The video is a newly generated mp4 file and I have the path to where it is stored on the device.

For pictures its done like this:

Drive.DriveApi.newDriveContents(mDriveClient).setResultCallback(
    new ResultCallback<DriveContentsResult>() {

@Override
public void onResult(DriveContentsResult result) {
    if (!result.getStatus().isSuccess()) {
        Log.i(TAG, "Failed to create new contents.");
        return;
    }
    OutputStream outputStream = result.getDriveContents().getOutputStream();
    // Write the bitmap data from it.
    ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 80, bitmapStream);
    try {
        outputStream.write(bitmapStream.toByteArray());
    } catch (IOException e1) {
        Log.i(TAG, "Unable to write file contents.");
    }
    image.recycle();
    outputStream = null;
    String title = Shared.getOutputMediaFile(Shared.MEDIA_TYPE_IMAGE).getName();
    MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
        .setMimeType("image/jpeg").setTitle(title)
        .build();
    Log.i(TAG, "Creating new pic on Drive (" + title + ")");

    Drive.DriveApi.getFolder(mDriveClient,
        mPicFolderDriveId).createFile(mDriveClient,
        metadataChangeSet, result.getDriveContents());
        }
    });
}

What I am interested in is an alternative for a File, in this case pointing to a "video/mp4".

like image 825
Patrick Forsyth Avatar asked Dec 09 '14 14:12

Patrick Forsyth


2 Answers

Without getting into much detail, just a few pointers:

Anything you want to upload (image, text, video,...) consists from

  1. creating a file
  2. setting metadata (title, MIME type, description,...)
  3. setting content (byte stream)

The demo you mention does it with an image (JPEG bytestream) and you need to do it with video. So, the changes you need to implement are:

  • replace the "image/jpeg" MIME type with the one you need for your video
  • copy your video stream (outputStream.write(bitmapStream.toByteArray())...)

to the content.

These are the only changes you need to make. Google Drive Android API doesn't care what is your content and metadata, it just grabs it a shoves it up to Google Drive.

In Google Drive, apps (web, android,...) read the metadata and content, and treat it accordingly.

like image 102
seanpj Avatar answered Sep 21 '22 08:09

seanpj


So this my complete code how I achieved uploading a video. Steps:

  • Fetch video file from uri(as in my case).
  • Get the byte array from bytearray outputstream as mentioned in the code
  • write the byte array to the ouputStream
  • the api will upload the file in the background

public class UploadVideo extends AppCompatActivity {

DriveClient mDriveClient;
DriveResourceClient mDriveResourceClient;
GoogleSignInAccount googleSignInAccount;
String TAG = "Drive";
private final int REQUEST_CODE_CREATOR = 2013;
Task<DriveContents> createContentsTask;
String uri;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_upload_video);
    //Fetching uri or path from previous activity.
    uri = getIntent().getStringExtra("uriVideo");
    //Get previously signed in account.
    googleSignInAccount = GoogleSignIn.getLastSignedInAccount(this);
    if (googleSignInAccount != null) {
        mDriveClient = Drive.getDriveClient(getApplicationContext(), googleSignInAccount);
        mDriveResourceClient =
                Drive.getDriveResourceClient(getApplicationContext(), googleSignInAccount);
    }
    else Toast.makeText(this, "Login again and retry", Toast.LENGTH_SHORT).show();
    createContentsTask = mDriveResourceClient.createContents();
    findViewById(R.id.uploadVideo).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
                createFile();
        }
    });
}

private void createFile() {
    // [START create_file]
    final Task<DriveFolder> rootFolderTask = mDriveResourceClient.getRootFolder();
    final Task<DriveContents> createContentsTask = mDriveResourceClient.createContents();
    Tasks.whenAll(rootFolderTask, createContentsTask)
            .continueWithTask(new Continuation<Void, Task<DriveFile>>() {
                @Override
                public Task<DriveFile> then(@NonNull Task<Void> task) throws Exception {
                    DriveFolder parent = rootFolderTask.getResult();
                    DriveContents contents = createContentsTask.getResult();
                    File file = new File(uri);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buf = new byte[1024];
                    FileInputStream fis = new FileInputStream(file);
                    for (int readNum; (readNum = fis.read(buf)) != -1;) {
                        baos.write(buf, 0, readNum);
                    }
                    OutputStream outputStream = contents.getOutputStream();
                    outputStream.write(baos.toByteArray());

                    MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                            .setTitle("MyVideo.mp4") // Provide you video name here
                            .setMimeType("video/mp4") // Provide you video type here
                            .build();

                    return mDriveResourceClient.createFile(parent, changeSet, contents);
                }
            })
            .addOnSuccessListener(this,
                    new OnSuccessListener<DriveFile>() {
                        @Override
                        public void onSuccess(DriveFile driveFile) {
                            Toast.makeText(Upload.this, "Upload Started", Toast.LENGTH_SHORT).show();
                            finish();
                        }
                    })
            .addOnFailureListener(this, new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.e(TAG, "Unable to create file", e);
                    finish();
                }
            });
    // [END create_file]
}

}

like image 40
Amlan Routray Avatar answered Sep 24 '22 08:09

Amlan Routray