Android-видео не поддерживает ориентацию при загрузке на веб-сайт

Я создал свою собственную активность в своем приложении для Android, чтобы записывать видеоролики, и, похоже, она работает очень хорошо: видео сохраняются в указанной папке в телефоне, когда я просматриваю их в галерее, у них правильная ориентация, и они Даже загружен на сервер amazon s3 без проблем.

Единственная проблема возникает, когда я просматриваю видео с сервера, они неправильно повернуты в зависимости от позиции, которую я записал.

Я устанавливаю подсказку ориентации видео, когда я записываю их, что позволяет правильно воспроизводить на моем устройстве, но не влияет на загруженное видео.

Вот код, который я использую для записи видео

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; } 

Затем начните запись:

 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 } } 

И для загрузки:

 @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; } 

Один из способов сделать это – просто вручную повернуть видео в приложении, но я слышал, что это очень дорого и слишком сильно замедлит приложение. Мне было интересно, был ли простой способ отправить метаданные ориентации на сайт и обработать серверы вращения.

Я использую рубин на сайте rails с камнем носителя, чтобы загрузить видео. Мне было интересно, был ли простой способ или какой-то тип информации, которую я мог бы передать в загрузку, чтобы узнать, что видео повернуто. Поскольку я могу извлечь эту информацию из видео и просто отправить ее в комплекте с MultipartEntity всякий раз, когда я отправляю ее с телефона.

Если вы используете веб-сайт Ruby on Rails, вы можете использовать FFMPEG, чтобы конвертировать ваши видео для правильной ориентации. Вам необходимо установить FFMPEG на свой сервер. Установка зависит от ОС и ОС. Но это очень просто.

Вот как вы можете конвертировать все видео в соответствии с ориентацией, которую вы отправляете на сервер. Просто установите условия для поворотов 90, 180, 270, 360 и выполните команду. Если вы не получите ориентировку, которую вы отправляете, вы можете использовать инструмент MiniExif для получения ориентации

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

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