Экранная видеозапись текущей активности Android

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

6 ответов


программная запись видео из вашего приложения потребует корневого доступа. Вы заметите, что приложения, доступные для этого в Play Store, заметно перечисляют "Требуется ROOT" в своих описаниях приложений. Вы также заметите, что для этого подхода также могут быть определенные требования к оборудованию ("не работает на Galaxy Nexus или Tegra 2/3...- ...из описания Скринкаст Видео Рекордер app.

Я никогда не писал этот код я сам, но я собрал очень высокую идею о требуемом подходе. Это вытекает из этого в должности что вы должны получить доступ к данным буфера кадров через "/dev / graphics / fb0". Режим доступа к буферу кадра 660, что означает, что вам нужен root доступ, чтобы добраться до него. После того, как у вас есть корневой доступ, вы можете использовать данные буфера кадров для создания снимков экрана (это проект может работать для этой задачи), а затем создать видео из этих игр (см. другой, так вопрос о том, как создание видео из последовательности изображений).

Я использовал приложение Screencast, и он хорошо работает на заметке Samsung. Я подозреваю, что это их основной подход.


поскольку Lollipop мы можем использовать API медиа-проекции ! (API 21+)

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

private static final int CAST_PERMISSION_CODE = 22;
private DisplayMetrics mDisplayMetrics;
private MediaProjection mMediaProjection;
private VirtualDisplay mVirtualDisplay;
private MediaRecorder mMediaRecorder;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mMediaRecorder = new MediaRecorder();

    mProjectionManager = (MediaProjectionManager) getSystemService
            (Context.MEDIA_PROJECTION_SERVICE);

    getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);

    prepareRecording();
}

private void startRecording() {
    // If mMediaProjection is null that means we didn't get a context, lets ask the user
    if (mMediaProjection == null) {
        // This asks for user permissions to capture the screen
        startActivityForResult(mProjectionManager.createScreenCaptureIntent(), CAST_PERMISSION_CODE);
        return;
    }
    mVirtualDisplay = createVirtualDisplay();
    mMediaRecorder.start();
}

private void stopRecording() {
    if (mMediaRecorder != null) {
        mMediaRecorder.stop();
        mMediaRecorder.reset();
    }
    if (mVirtualDisplay != null) {
        mVirtualDisplay.release();
    }
    if (mMediaProjection != null) {
        mMediaProjection.stop();
    }
    prepareRecording();
}

public String getCurSysDate() {
    return new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date());
}

private void prepareRecording() {
    try {
        mMediaRecorder.prepare();
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }

    final String directory = Environment.getExternalStorageDirectory() + File.separator + "Recordings";
    if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
        Toast.makeText(this, "Failed to get External Storage", Toast.LENGTH_SHORT).show();
        return;
    }
    final File folder = new File(directory);
    boolean success = true;
    if (!folder.exists()) {
        success = folder.mkdir();
    }
    String filePath;
    if (success) {
        String videoName = ("capture_" + getCurSysDate() + ".mp4");
        filePath = directory + File.separator + videoName;
    } else {
        Toast.makeText(this, "Failed to create Recordings directory", Toast.LENGTH_SHORT).show();
        return;
    }

    int width = mDisplayMetrics.widthPixels;
    int height = mDisplayMetrics.heightPixels;

    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
    mMediaRecorder.setVideoFrameRate(30);
    mMediaRecorder.setVideoSize(width, height);
    mMediaRecorder.setOutputFile(filePath);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode != CAST_PERMISSION_CODE) {
        // Where did we get this request from ? -_-
        Log.w(TAG, "Unknown request code: " + requestCode);
        return;
    }
    if (resultCode != RESULT_OK) {
        Toast.makeText(this, "Screen Cast Permission Denied :(", Toast.LENGTH_SHORT).show();
        return;
    }
    mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
    // TODO Register a callback that will listen onStop and release & prepare the recorder for next recording
    // mMediaProjection.registerCallback(callback, null);
    mVirtualDisplay = getVirtualDisplay();
    mMediaRecorder.start();
}

private VirtualDisplay getVirtualDisplay() {
    screenDensity = mDisplayMetrics.densityDpi;
    int width = mDisplayMetrics.widthPixels;
    int height = mDisplayMetrics.heightPixels;

    return mMediaProjection.createVirtualDisplay(this.getClass().getSimpleName(),
            width, height, screenDensity,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            mMediaRecorder.getSurface(), null /*Callbacks*/, null /*Handler*/);
}

Это не окончательный код, но хорошая база для начала :)


обычным приложениям Android не хватает разрешения на захват буфера кадров (в частности, они не являются членами группы AID_GRAPHICS). Это по соображениям безопасности-иначе они могли бы вынюхивать пароли и т. д. с мягкой клавиатуры. Таким образом, в целом вы не можете захватить экран из приложения Android без какого-либо способа обойти проблему привилегий.

вы можете более или менее захватить снимок области экрана, в настоящее время занятой вашим приложением, перейдя в Вид сверху в иерархии представлений и рисования его в растровое изображение с помощью View.draw (Canvas), однако это не будет записывать строку состояния, мягкую клавиатуру, поверхности OpenGL и т. д.

Если вы хотите сделать лучше, чем это необходимо использовать внешний инструмент. Инструментам нужен root или интерфейс ADB, поскольку процессы, запущенные через интерфейс ADB, имеют привилегию AID_GRAPHICS. Используя последний метод, непривилегированное приложение может подключиться к привилегированному серверу для записи.

грубо инструменты можно разделить на следующие категории:

  • Root-только приложения для записи кадров (например, Screencast). Эти записи непосредственно с устройства /dev / graphics / fb0, но работают только на устройствах, где фреймбуфер читается (e.g, не на Tegra 2 Nexus 7).

  • Root-только приложения для захвата экрана (например, SCR, Rec и т. д.). Они захватывают экран через SurfaceFlinger и работают на гораздо более широком диапазоне устройства.

  • Non root Screen capture recorder приложения (например, записываемые, Ascrecorder). Они требуют, чтобы пользователь включил отладку USB и запустил демона при подключении через хост-ПК. После этого хост-ПК не требуется до перезагрузки устройства. Может записывать аудио, а также.

  • инструменты ADB (например, встроенный screenrecorder на Android 4.4). Требуется подключение через USB и не удается захватить звуковой.

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

http://recordable.mobi/compare

для полноты есть также USB-инструменты (например, Mobizen), которые передают экран через USB (ограниченный низким диапазоном USB и не могут записывать аудио), а некоторые устройства также могут передавать экран через wifi, который затем может быть захвачен на отдельном устройстве.


Это довольно старый пост, но я надеюсь, что это поможет кому-то, кто все еще ищет способ записи экрана устройства android:

Так как Android 5.0 есть новый API, который можно использовать для записи экрана: MediaProjection MediaProjection предоставляет возможность захвата содержимого экрана, но не системного звука. Также он не будет захватывать безопасное содержимое экрана.

на странице Matt Snider есть хороший пример того, как использовать API для фактически запишите экран в файл на sdcard:ссылке


вы можете захватить экран с помощью DDMS, как adb работает и имеет разрешение на framebuffer:

перейдите по этой ссылке для более подробной информации :

http://thetechjournal.com/electronics/android/how-to-capture-screenshots-and-record-video-on-android-device.xhtml

также проверьте эти ссылки, возможно, получите некоторые идеи о том, что вам нужно :

http://answers.oreilly.com/topic/951-how-to-capture-video-of-the-screen-on-android/

http://www.mightypocket.com/2010/09/installing-android-screenshots-screen-capture-screen-cast-for-windows/

и проверьте этот проект:

http://sourceforge.net/projects/ashot/

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


вы можете записать вас экран таким образом тоже: http://www.youtube.com/watch?v=4K2UDfP4lN8&list=UU4fDGas-Vz1xruuUY4QbF0w&feature=c4-overview.

видео называется " Как захватить / записать экран Android без Root (Mobizen)".

ссылка на видео Использование Mobizen:https://play.google.com/store/apps/details?id=com.rsupport.mvagent