Подтвердить что ты не робот

Записывайте видео с другим размером предварительного просмотра, чем полученный видеофайл

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

Если возвращенный список не является нулевым, возвращаемый список будет содержать как минимум один Размер и один из размеров в возвращаемом списке должны быть передан в MediaRecorder.setVideoSize() для приложения для видеокамеры, если камера используется в качестве источника видеосигнала. В этом случае размер предварительный просмотр может отличаться от разрешения записанного видео во время видеозаписи.

Это говорит о том, что некоторые телефоны вернут null из этого fn (по моему опыту Galaxy SIII), но для тех, кто этого не делает, можно предоставить предварительный просмотр с другим разрешением, чем фактическое видео. Правильно ли это понимание? Некоторые телефоны позволяют поведение, а другие нет?

Попытка решения:

В официальном описании функции setPreviewDisplay, которая используется в длительный процесс настройки видеозаписи, упоминается, что:

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

Это похоже на то, что я хочу, но, к сожалению, если я это сделаю, весь процесс записи видео полностью перепутался. Я предполагаю, что эта функция не может быть передана null или вообще не вызвана в процессе записи видео. Возможно, в других контекстах это нормально. К сожалению, это, похоже, не помогает мне.

Мои следующие шаги - изучить TextureView и использовать текстуру предварительного просмотра в отличие от типичной реализации SurfaceView, чтобы использовать openGL для растягивания текстуры до желаемого размера, который отличается от фактического разрешения (и обрезает любой избыток экрана), а затем для построения поверхности для функции setPreviewDisplay с конструктором Surface(SurfaceTexture surfaceTexture) для поверхности. Я бы хотел избежать использования TextureView из-за несовместимости ниже ICS, а также потому, что это добавляет значительную сложность.

Это похоже на деликатный процесс, но я надеюсь, что кто-то может предложить некоторые советы в этой области.

Спасибо.

4b9b3361

Ответ 1

a. Укажите, что пользователь устанавливает размер x, y как размер видео

b.Затем функция getSupportedVideoSizes получает весь список и видит, что x, y попадает в один из них и устанавливает MediaRecorder.setVideoSize(). Если x, y не попадает в список getSupportedVideoSizes, тогда задайте профиль по умолчанию для видеозаписи.

Это размер видео

Теперь, приходя к размеру предварительного просмотра, не так много вариантов обхода. Возьмите RelativeLayout, который содержит SurfaceView.

<android.view.SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/preview"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 />

preview - это имя SurfaceView. Здесь я дал образец для повторной калибровки его на половину ширины и высоты.

resetCamera();  //reset the camera   

ViewGroup.LayoutParams params = preview.getLayoutParams();
RelativeLayout myRelLayout = (RelativeLayout) findViewById(R.id.myRelLayout);
params.width = (int) (myRelLayout.getWidth()/2);
params.height = (int)(myRelLayout.getHeight()/2);
preview.setLayoutParams(params);

initCamera(); //initiate the camera(open camera, set parameter, setPreviewDisplay,startPreview)

просмотрите разрешение предварительного просмотра, а затем уменьшите размер или ширину соответственно на основе размера видео.

Надеюсь, что это поможет.

Ответ 2

Как вы упомянули, это возможно только тогда, когда getSupportedVideoSizes() возвращает ненулевой список.

Но если вы видите непустой список, тогда этот простой подход должен работать:

  • Установите желаемое разрешение предварительного просмотра с помощью setPreviewSize; выбранный вами размер должен быть одним из размеров, указанных в getSupportedPreviewSizes.

  • Установите отображение предварительного просмотра в SurfaceView или SurfaceTexture с помощью setPreviewDisplay или setPreviewTexture, соответственно.

  • Предварительный просмотр.

  • Создайте медиа-рекордер и установите его размер видео непосредственно с помощью setVideoSize, используя один из размеров от getSupportedVideoSizes или используйте один из предопределенных профилей видеокамер, чтобы настроить все настройки медиа-рекордера для заданного качества/размера.

  • Передайте объект камеры MediaRecorder setCamera, настройте остальную часть медиа-рекордера и начните запись.

На устройствах с ненулевым списком getSupportedVideoSizes это приведет к тому, что предварительный просмотр останется в разрешении, заданном вашим вызовом setPreviewSize, при этом запись будет работать с заданным разрешением размера видео/видеокамеры. На устройствах без поддерживаемых размеров видео размер файла предварительного просмотра будет reset в MediaRecorder, чтобы соответствовать размеру записи. Вы должны проверить это, установив очень низкое разрешение предварительного просмотра и высокое разрешение записи (скажем, 160x120 для предварительного просмотра, 720p для записи). Это должно быть очевидно, если MediaRecorder переключит разрешение предварительного просмотра на 720p при начале записи, так как качество предварительного просмотра существенно скажется.

Обратите внимание: размер предварительного просмотра напрямую не связан с размерами экрана SurfaceView; вывод предварительного просмотра камеры будет масштабироваться, чтобы вписаться в SurfaceView, поэтому, если ваши размеры SurfaceView, скажем, 100x100 пикселей из-за вашего макета и устройства, независимо от того, какое разрешение для просмотра вы используете, будет масштабироваться до 100x100 для отображения. Поэтому вам все равно нужно убедиться, что соотношение сторон SurfaceView правильное, чтобы предварительный просмотр не искажался.

И для энергоэффективности вы не должны использовать разрешение предварительного просмотра намного выше фактического количества пикселей в SurfaceView, так как дополнительное разрешение будет потеряно при установке предварительного просмотра в режиме просмотра поверхности. Это, конечно, возможно только для записи, когда getSupportedVideoSizes() возвращает ненулевое значение.

Ответ 3

Во-первых, я постараюсь ответить на ваши конкретные вопросы.

  • можно предоставить предварительный просмотр с другим разрешением, чем фактическое видео. Правильно ли это понимание?

Да, размер предварительного просмотра чаще всего отличается от размера записи. Размер предварительного просмотра чаще всего не связан с вашим размером экрана. Поэтому, если на телефоне отображается CIF (352 x 288), но он способен записывать D1 (720 x 480), размер предварительного просмотра и размер записи будут разными. Я чувствую, что другие эксперты достаточно ответили на этот вопрос.

  • Некоторые телефоны позволяют поведение, а другие нет?

Большинство последних телефонов поддерживают эту функцию, за исключением, возможно, нескольких low-end.

Наряду с setPreviewDisplay, мы должны также рассмотреть эту точку:

Единственное исключение состоит в том, что если поверхность предварительного просмотра не установлена ​​(или установлена ​​в нуль) до вызова startPreview(), этот метод может быть вызван один раз с ненулевым параметром для установки поверхности предварительного просмотра. (Это позволяет осуществлять настройку камеры и создание поверхности параллельно, экономя время.) Поверхность предварительного просмотра, возможно, не изменится во время предварительного просмотра.

Не могли бы вы рассказать о проблеме, с которой вы столкнулись, когда setPreviewDisplay вызывается с поверхностью NULL?