user2859895
user2859895

Reputation: 41

Android video not maintaining orientation when uploaded to website

I have created my own activity in my Android app to record videos and it seems to work just fine: the videos are being saved to the specified folder in the phone, whenever I view them in the gallery they have the correct orientation, and they are even uploaded to the amazon s3 server with no issues.

The only problem happens when I go to view the videos from the server, they aren't correctly rotated based on the position that I recorded them.

I am setting the video's orientation hint whenever I record them which allows for the correct playback on my device, but has no effect on the uploaded video.

Here's the code I use to record the video

private boolean prepareVideoRecorder() {
    // It is very important to unlock the camera before doing setCamera
    // or it will results in a black preview
    if (camera == null) 
    {
        camera = getCameraInstance();
    }

    if (recorder == null){
        recorder = new MediaRecorder();
    }
    //Have to stop preview before starting to record
    camera.stopPreview();
    // Step 1: Unlock and set camera to MediaRecorder
    camera.unlock();
    recorder.setCamera(camera);

    // Step 2: Set sources
    recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

    // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
    recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

    // Step 4: Set output file
    recorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).getAbsolutePath());

    // No limit. Don't forget to check the space on disk.
    recorder.setMaxDuration(50000);
    recorder.setVideoFrameRate(30);
    recorder.setVideoEncodingBitRate(3000000);
    recorder.setAudioEncodingBitRate(8000);

    // Step 5: Set the preview output
    recorder.setPreviewDisplay(cameraPreview.getHolder().getSurface());

    //Setting the camera's orientation
    int degree = 0;
    // do not rotate image, just put rotation info in
    switch (mOrientation) {
        case ORIENTATION_LANDSCAPE_INVERTED:
            degree = 180;
            break;
        case ORIENTATION_PORTRAIT_NORMAL:
            degree = 90;
            break;
        case ORIENTATION_LANDSCAPE_NORMAL:
            degree = 0;
            break;
        case ORIENTATION_PORTRAIT_INVERTED:
            degree = 270;
            break;
    }

    recorder.setOrientationHint(degree);

    // Step 6: Prepare configured MediaRecorder
    try {
        recorder.prepare();
    } catch (IllegalStateException e) {
        // This is thrown if the previous calls are not called with the
        // proper order
        e.printStackTrace();
        releaseMediaRecorder();
        return false;
    } catch (IOException e) {
        releaseMediaRecorder();
        e.printStackTrace();
        return false;
    }        
    //Everything went successfully
    return true;
}

Then start recording:

private void startRecording(){
    //TODO: Draw stuff to let user know when they are recording
    // initialize video camera
    if (prepareVideoRecorder()) {
        //Assuring the app doesn't go to sleep while recording
        timerView.setKeepScreenOn(true);

        //"Adding" timer whenever we start to record
        timerView.setVisibility(View.VISIBLE);

        // Camera is available and unlocked, MediaRecorder is prepared,
        // now you can start recording
        recorder.start();

        // inform the user that recording has started
        shutter.setBackgroundResource(R.drawable.custom_button_red);
        isRecording = true;

        //TODO:Testing timer stuff
        startTimer();
    } else {
        // prepare didn't work, release the camera
        releaseMediaRecorder();
        // inform user
    }
}

And for uploading:

@Override
    protected HttpEntity doInBackground(Object... params){
        DefaultHttpClient client = new DefaultHttpClient();
        String stepID = (String)params[0];
        filepath = (String)params[1];
        String auth_token = (String)params[2];
        String projectID = (String)params[3];

        String filename = Uri.parse(filepath).getLastPathSegment().toString();
        String videoType = filename.substring(filename.lastIndexOf("."), filename.length());

        String url = VIDEO_URL+"?auth_token=" + auth_token;

        HttpPost post = new HttpPost(url);
        HttpContext localContext = new BasicHttpContext();
        MultipartEntity imageMPentity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

        try{

            imageMPentity.addPart("project_id", new StringBody(""+projectID));
            imageMPentity.addPart("step_id", new StringBody(stepID));
            imageMPentity.addPart("content_type", new StringBody("video/"+videoType));
            imageMPentity.addPart("filename", new StringBody(filename));
            imageMPentity.addPart("video_path", new FileBody(new File(filepath)));       
            post.setEntity(imageMPentity);                

        } catch(Exception e){
            Log.e(StepDisplay.class.getName(), e.getLocalizedMessage(), e);
        }
        HttpResponse response = null;

        try {
            response = client.execute(post, localContext);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        HttpEntity result = null;

        if(response != null){
             result = response.getEntity();
        }
        return result;
    }

A way I have though of doing this is to just manually rotate the videos in the application, but I have heard it is very costly and would slow down the app too much. I was wondering if there was a simple way to send the orientation metadata to the website and handle the rotation serverside.

I am using a ruby on rails website with the carrierwave gem to upload the videos. I was wondering if there was a simple method or some type of information I could pass to the upload in order to have it recognize that the video is rotated. As I can extract this info from the videos and simple send it bundled in the MultipartEntity whenever I send it from the phone.

Upvotes: 4

Views: 997

Answers (1)

Aditya Kamatar
Aditya Kamatar

Reputation: 363

If you are using a Ruby on Rails Website you can use FFMPEG to convert your videos to correct orientation. You need to install FFMPEG on your server. Installation varies from OS to OS But it's very simple.

Here is how you can convert all the videos according the orientation you as sending to the server. Just put conditions for the rotations 90 , 180 , 270 , 360 and run the command. If you don't get the orientation which you are sending , you can use MiniExif Tool to get the orientations

ffmpeg -i in.mov -vf "transpose=1" out.mov

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

Upvotes: 1

Related Questions