создание камеры для LG Optimus GT540 | пробуем вернуть камере нормальный битрейт



Реп: (23)
Предыстория: После обновления прошивки на 2.1 заметно ухудшилось качество видео.
На сегодня существует приложение http://www.dailyroads.com/voyager/download, которое даёт нормальное качество видео.
Для простоты эксперимента, возьмём этот видеорекордер:
http://www.codeproject.com/KB/android/Andr...oComponent.aspx (проект будет приложен к посту)
Сейчас можно уверенно сказать, что параметры, которые отвечают за кодек, контейнер и разрешение ясны:
Для конкретного приложения это следующие строки в VideoRecorder.java
recorder = new MediaRecorder();
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); //Заменён контейнер c 3gp на mp4
recorder.setVideoSize(640, 480); //Строка добавлена, по умолчанию камера снимает в 320x240
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); //Заменён кодек с h.263 на mp4v
...
tempRecorder.setOutputFile("/sdcard/recordvideooutput.mp4"); //Заменено расширение с 3gpp на mp4

Всё интуитивно понятно, а вот с битрейтом сложнее:
Указать битрейт, средствами api ниже level 8 (Android 2.2) нельзя, но существует DailyRoads Voyager, которая позволяет снимать видео с битрейтом 1800 кбит/сек на gt540 c android 2.1
Вот пост её автора:
http://community.developer.motorola.com/t5...age/true/page/1
Re: 720x480 video recording on Milestone
08-28-2010 12:43 PM

I also wanted to improve video recording quality in my app, and looked inside the source code of the native camera app. There they used MediaRecorder.setParameters(String), which has never been part of the public API, but it works on Android 2.1. To control the bitrate you'd provide a parameter like:

setParameters("video-param-encoding-bitrate=1000000");

As this method is not part of the public API, you'd need to use it through reflection.

Robert
---
DailyRoads Voyager
http://www.dailyroads.com/voyager

Вероятнее всего используются недокументированные возможности api:
http://code.google.com/p/android/issues/detail?id=5052
Собственно, основная проблема сейчас, это как вставить этот код в VideoRecorder.java из VideoComponent.zip
Для работы Вам потребуются:
http://www.eclipse.org/downloads/ (Например Eclipse Classic 3.6.1)
и
http://developer.android.com/sdk/index.html

Также интересно содержание файла build.prop
Возможно он содержит (может содержать) данные спойлера (это означало бы, что есть возможность задать минимальный битрейт.)
ro.media.enc.file.format = 3gp,mp4
ro.media.enc.vid.codec = m4v,h263
ro.media.enc.vid.h263.width = 176,1280
ro.media.enc.vid.h263.height = 144,720
ro.media.enc.vid.h263.bps = 64000,2000000
ro.media.enc.vid.h263.fps = 1,30
ro.media.enc.vid.m4v.width = 176,1280
ro.media.enc.vid.m4v.height = 144,720
ro.media.enc.vid.m4v.bps = 64000,2000000
ro.media.enc.vid.m4v.fps = 1,30


Прикрепленные файлы

Прикрепленный файлVideoRecorder.java.zip ( 1.78 КБ )
Прикрепленный файлVideoComponent.zip ( 39.2 КБ )


Сообщение отредактировал ugehuc - 05.10.10, 11:48



Реп: (23)
Вот ответ про метод "through reflection"
http://groups.google.com/group/android-dis...28889de6383f446



Реп: (1395)
Код бы лучше показали.
А то я попробовал сделать через setParameters, но ничего особо не поменялось.



Реп: (23)
RubberBigPepper @ 05.10.2010, 16:25 *
Код бы лучше показали.

Какой код? Вы же не про этот?: (:
Рабочий код для явного указания кодека/контейнера/разрешения/расширения, как в (1.6)
VideoRecorder.java
да понятно ни о чём убираю :)


Нашёл автора, <Robert Fejer> robert@dailyroads.com он зарегистрирован у нас на форуме:
http://4pda.to/forum/index.php?act=Msg&CODE=4&MID=1201388

Сообщение отредактировал ugehuc - 05.10.10, 19:49



Реп: (1395)
Этот код ни о чем.
Короче, сделал в своем приложении сам(на 1.6 не работало, на 2.1 запустилось, 640 на 480 хоть 3мбита битрейт можно поставить).
Код примерно такой:
try
{
m_cSetParam=m_cRecorder.getClass().getMethod("setParameters", String.class);
m_cSetBitRate=m_cRecorder.getClass().getMethod("setVideoEncodingBitRate", Integer.TYPE);
}
catch(Exception ex)
{

}

m_cRecorder.setVideoFrameRate(30);
m_cRecorder.setVideoSize(m_ptSize.x,m_ptSize.y);

if(m_bManualBitRate)
{
try
{
if(m_cSetBitRate!=null)
m_cSetBitRate.invoke(m_cRecorder,m_nBitRate);
else
m_cSetParam.invoke(m_cRecorder,String.format("video-param-encoding-bitrate=%d",m_nBitRate));
}
catch(Exception ex)
{
//ex.printStackTrace();
}
}

m_cRecorder.setVideoEncoder(m_nFormat);


Сообщение отредактировал RubberBigPepper - 05.10.10, 19:45



Реп: (23)
RubberBigPepper @ 05.10.2010, 20:44 *
Этот код ни о чем.
Короче, сделал в своем приложении сам(на 1.6 не работало, на 2.1 запустилось, 640 на 480 хоть 3мбита битрейт можно поставить).
Код примерно такой:

Видео покажите ))
RubberBigPepper @ 05.10.2010, 20:44 *
setVideoFrameRate(30)

Только на LG GT540 всё равно 17 будет
А ясно, Вы автор видеорегистратора :)

Сообщение отредактировал ugehuc - 05.10.10, 20:19



Реп: (23)
Рабочий код для тестового приложения:
recorder = new MediaRecorder();
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // Заменён контейнер c 3gp на mp4
recorder.setVideoSize(640, 480); // Строка добавлена, по умолчанию камера снимает в 320x240
Method m_cSetParam = null; // Начало кода, отвечающего за битрейт.
try
{
m_cSetParam=recorder.getClass().getMethod("setParameters", String.class);
}
catch(Exception ex)
{

}

try
{
m_cSetParam.invoke(recorder,String.format("video-param-encoding-bitrate=%d",2000000)); // Указание битрейта.
}
catch(Exception ex)
{

} // Конец кода, отвечающего за битрейт.
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); // Явное указание кодека mpv4
...
tempRecorder.setOutputFile("/sdcard/recordvideooutput.mp4]"); // Заменено расширение с 3gpp на mp4

Спасибо RubberBigPepper и dailyroads (:

Сообщение отредактировал ugehuc - 06.10.10, 08:22



Реп: (23)
Вот скомпилированные:
Теперь нужно найти нормальный видеорекордер с открытым кодом,
или пытаться ковырять приложение lg

Прикрепленные файлы

Прикрепленный файл640x480.mp4v.2000kbps.apk ( 11.99 КБ )
Прикрепленный файл640x480.mp4v.3000kbps.apk ( 12.01 КБ )
Прикрепленный файл640x480.mp4v.5000kbps.apk ( 12.01 КБ )
Прикрепленный файл640x480.h263.2000kbps.apk ( 12.01 КБ )
Прикрепленный файл640x480.h263.3000kbps.apk ( 12 КБ )
Прикрепленный файл640x480.h263.5000kbps.apk ( 12.01 КБ )



Реп: (1395)
ИМХО, идея вообще бесперспективная.
Если хочется снимать видео в нормальном разрешении - берите DailyRoadsVoyager, ну или мою :)
А делать приложение камера, которое через месяц-два устареет и отомрет-кто согласится?Тем более за просто так.



Реп: (129)
ugehuc @ 06.10.2010, 10:38 *
Прикрепленный файл640x480.mp4v.5000kbps.apk


Неплохо пишет, только без звука. А так спасибо, что работаете в этом направлении :thank_you:



Реп: (7)
640x480.mp4v.3000kbps.apk

ugehuc,

Видеозапись отличная получается. А можно звук прикрутить к этим маленьким программкам?

Наверное нужно добавить чтото типа:

recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //или вместо AMR_NB - DEFAULT поставить?


И еще как нибудь объединить все в одну прогу с выбором кодека и битрейта.

Сообщение отредактировал Toliksol - 11.10.10, 13:15



Реп: (7)
Наклепал тут тестовое приложение :) Пишет со звуком :)
(только в манифест добавил еще разрешение чтоб звук записывать :) android.permission.RECORD_AUDIO )

recorder = new MediaRecorder();

recorder.setAudioSource(MediaRecorder.AudioSource.MIC); // или MIC?
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);

recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // Заменён контейнер c 3gp на mp4
recorder.setVideoSize(640, 480); // Строка добавлена, по умолчанию камера снимает в 320x240

// Начало кода, отвечающего за битрейт.
Method m_cSetParam = null;
try
{
m_cSetParam=recorder.getClass().getMethod("setParameters", String.class);
}
catch(Exception ex)
{
}
try
{
m_cSetParam.invoke(recorder,String.format("video-param-encoding-bitrate=%d",2000000)); // Указание битрейта.
}
catch(Exception ex)
{
}
// Конец кода, отвечающего за битрейт.

recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //или вместо AMR_NB - DEFAULT поставить?
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); // Явное указание кодека mpv4


Прикрепленные файлы

Прикрепленный файлVideoComponent.apk ( 12.03 КБ )



Реп: (7)
Еще небольшое изменение внес:
Сделал чтоб создавалось уникальное имя файла (чтоб один и тот же файл не перезаписывался) надо только разобраться как сделать чтоб дата нормальная была в имени файла.

long timeInMillis = System.currentTimeMillis(); //Добавил создание уникального имени файла
File nextFile = new File("/sdcard/" + timeInMillis + ".mp4"); //
tempRecorder.setOutputFile(nextFile.getAbsolutePath()); //


Прикрепленные файлы

Прикрепленный файлCamera_3000_mp4.apk ( 12.27 КБ )
Прикрепленный файлCamera_5000_mp4.apk ( 12.27 КБ )



Реп: (1395)
Toliksol @ 11.10.2010, 22:50 *
надо только разобраться как сделать чтоб дата нормальная была в имени файла.

Я делаю так:
m_cCurTime.setToNow();
String strName=String.format("/%04d_%02d_%02d__%02d_%02d_%02d.%s",m_cCurTime.year,(m_cCurTime.month+1),m_cCurTime.monthDay,
m_cCurTime.hour,m_cCurTime.minute,m_cCurTime.second,strExt);



Реп: (7)
RubberBigPepper,

Ясно.

А не пробовал менять параметры звука?

mMediaRecorder.setParameters(String.format("audio-param-encoding-bitrate=%d", mProfile.mAudioBitrate));
mMediaRecorder.setParameters(String.format("audio-param-number-of-channels=%d", mProfile.mAudioChannels));
mMediaRecorder.setParameters(String.format("audio-param-sampling-rate=%d", mProfile.mAudioSamplingRate));


Пробовал "audio-param-sampling-rate" ставить 16000 или 22100, вылетает программа...



Реп: (1395)
Toliksol @ 11.10.2010, 23:37 *
Пробовал "audio-param-sampling-rate" ставить 16000 или 22100, вылетает программа...

Не пробовал, для моих нужд звук не так важен. В try-catch загони и смотри, что за ексепшн вылазит.
Я вообще бы поостерегся играться с setParameters - все-таки недокументированная возможность. Вот на прошивке 1.6 вообще не работает.



Реп: (7)
RubberBigPepper @ 11.10.2010, 23:28 *
Я делаю так:
Код
m_cCurTime.setToNow();
String strName=String.format("/%04d_%02d_%02d__%02d_%02d_%02d.%s",m_cCurTime.year,(m_cCurTime.month+1),m_cCurTime.monthDay,
m_cCurTime.hour,m_cCurTime.minute,m_cCurTime.second,strExt);


Благодаря подсказке от RubberBigPepper, дату сделал в читабельном виде :)

Time time = new Time();
time.setToNow();
String strName=String.format("/%04d_%02d_%02d__%02d_%02d_%02d",time.year,(time.month+1),time.monthDay,time.hour,time.minute,time.second);
tempRecorder.setOutputFile("/sdcard/" + strName + ".mp4");


Прикрепленные файлы

Прикрепленный файлCamera_h263_2000_new.apk ( 12.31 КБ )
Прикрепленный файлCamera_h263_3000_new.apk ( 12.31 КБ )
Прикрепленный файлCamera_h263_5000_new.apk ( 12.31 КБ )
Прикрепленный файлCamera_h264_2000_new.apk ( 12.31 КБ )
Прикрепленный файлCamera_h264_3000_new.apk ( 12.31 КБ )
Прикрепленный файлCamera_h264_5000_new.apk ( 12.31 КБ )
Прикрепленный файлCamera_mp4_2000_new.apk ( 12.31 КБ )
Прикрепленный файлCamera_mp4_3000_new.apk ( 12.31 КБ )
Прикрепленный файлCamera_mp4_5000_new.apk ( 12.31 КБ )


Сообщение отредактировал Toliksol - 11.10.10, 22:19
Причина редактирования: Добавил другие кодеки



Реп: (7)
ugehuc @ 05.10.2010, 14:38 *
Также интересно содержание файла build.prop
Возможно он содержит (может содержать) данные спойлера (это означало бы, что есть возможность задать минимальный битрейт.)
Спойлер (+/-)
ro.media.enc.file.format = 3gp,mp4
ro.media.enc.vid.codec = m4v,h263
ro.media.enc.vid.h263.width = 176,1280
ro.media.enc.vid.h263.height = 144,720
ro.media.enc.vid.h263.bps = 64000,2000000
ro.media.enc.vid.h263.fps = 1,30
ro.media.enc.vid.m4v.width = 176,1280
ro.media.enc.vid.m4v.height = 144,720
ro.media.enc.vid.m4v.bps = 64000,2000000
ro.media.enc.vid.m4v.fps = 1,30

ugehuc,

А этот файл где лежит? Редактировать его можно только с рутом?



Реп: (1747)
Toliksol, \System там он лежит. Редактировать только под рутом.
Таких параметров у нас там нету.



Реп: (23)
В system, но у нас там нет ничего подобного.
Максимальный номинальный битрейт видео 6000 0000.

Про аудио можно в эту сторону копать:

MediaRecorder supports undocumented codec

MediaRecorder.AudioEncoder.AAC
MediaRecorder.AudioEncoder.AAC_PLUS
MediaRecorder.AudioEncoder.EAAC_PLUS
MediaRecorder.AudioEncoder.AMR_WB


и в эту:

private static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
...
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
frequency, channelConfiguration,
audioEncoding, bufferSize);


Хотя наверное pcm, не получится поместить в mp4 контейнер. Два файла рядом, не выход?

Сообщение отредактировал ugehuc - 12.10.10, 10:12


Полная версия   Текстовая версия

Помощь   Правила

Сейчас: 19.06.24, 00:01