image/svg+xml $ $ ing$ ing$ ces$ ces$ Res Res ea ea Res->ea ou ou Res->ou r r ea->r ch ch ea->ch r->ces$ r->ch ch->$ ch->ing$ T T T->ea ou->r

Permissions d'acquisition audio et vidéo

MediaRecorder

API

États de MediaRecorder

Source

Exemple

Exemple de l'utilisation de MediaRecorder pour enregistrer une vidéo de l'écran de l'appareil en utilisant MediaProjector :

// Code sample from Coursand [http://igm.univ-mlv.fr/~chilowi/], under the Apache 2.0 License

package fr.upem.coursand.screenrecorder

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.hardware.display.DisplayManager
import android.media.MediaRecorder
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.annotation.RequiresApi
import android.util.DisplayMetrics
import android.hardware.display.VirtualDisplay
import android.os.Environment
import androidx.core.content.ContextCompat
import android.widget.Toast
import fr.upem.coursand.R
import fr.upem.coursand.launcher.ActivityMetadata
import kotlinx.android.synthetic.main.activity_screen_recorder.*
import java.io.File


@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
@ActivityMetadata(permissions= [Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO], minApi=Build.VERSION_CODES.LOLLIPOP)
class ScreenRecorderActivity : AppCompatActivity() {
    val CAPTURE_REQUEST_ID = 1

    private val mediaProjectionManager by lazy { getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager }

    private var mediaProjection: MediaProjection? = null

    private val displayMetrics by lazy {
        val metrics = DisplayMetrics()
        windowManager.defaultDisplay.getMetrics(metrics)
        metrics
    }

    private val mediaRecorder by lazy { MediaRecorder() }

    private var virtualDisplay: VirtualDisplay? = null

    private var mediaProjectionCallback = object: MediaProjection.Callback() {
        override fun onStop() {
            super.onStop()
            stopMediaRecorder()
        }
    }

    var name: String? = null
    private var temporaryFile: File? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_screen_recorder)
        startButton.setOnClickListener { createMediaProjector() }
        stopButton.setOnClickListener { stopMediaRecorder() }
        recordAudioView.isEnabled = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED
        val recordable = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
        startButton.isEnabled = recordable
        if (! recordable)
            Toast.makeText(this, "The permission WRITE_EXTERNAL_STORAGE is not granted", Toast.LENGTH_SHORT).show()
    }

    private fun createMediaProjector() {
        if (mediaProjection != null) return // nothing to do it is already created
        startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), CAPTURE_REQUEST_ID)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == CAPTURE_REQUEST_ID && resultCode == Activity.RESULT_OK && data != null) {
            val mp = mediaProjectionManager.getMediaProjection(resultCode, data)
            mediaProjection = mp
            mp.registerCallback(mediaProjectionCallback, null)
            startMediaRecorder(nameView.text.toString())
        }
    }

    private fun startMediaRecorder(givenName: String) {
        startButton.isEnabled = false
        stopButton.isEnabled = true
        mediaRecorder.apply {
            val audio = recordAudioView.isChecked
            if (audio) setAudioSource(MediaRecorder.AudioSource.MIC)
            setVideoSource(MediaRecorder.VideoSource.SURFACE)
            setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
            val tmpFile = File.createTempFile("screenRecord", ".mp4", Environment.getExternalStorageDirectory())
            temporaryFile = tmpFile
            name = givenName
            setOutputFile(tmpFile.absolutePath)
            setVideoSize(displayMetrics.widthPixels, displayMetrics.heightPixels)
            setVideoEncoder(MediaRecorder.VideoEncoder.H264)
            if (audio) setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
            setVideoEncodingBitRate(512 * 1000)
            setVideoFrameRate(30)
            prepare()
            virtualDisplay = mediaProjection?.createVirtualDisplay("screenRecorder",
                    displayMetrics.widthPixels, displayMetrics.heightPixels, displayMetrics.densityDpi,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.surface, null, null)
            start()
        }
    }

    private fun stopMediaRecorder() {
        mediaRecorder.stop()
        mediaRecorder.reset()
        mediaProjection?.apply {
            unregisterCallback(mediaProjectionCallback)
            stop()
        }
        virtualDisplay?.release()
        virtualDisplay = null
        mediaProjection = null
        val uri = saveInMediaStore(MediaType.VIDEO, "video/mp4", name!!, temporaryFile!!)
        Toast.makeText(this, "Saved to $uri", Toast.LENGTH_SHORT).show()
        startButton.isEnabled = true
        stopButton.isEnabled = false
    }


}

Camera

Appel de l'application caméra

Exemple d'activité appelant l'application caméra de l'appareil pour enregister une photo ou vidéo.
Ne nécessite pas de permission spécifique

// Code sample from Coursand [http://igm.univ-mlv.fr/~chilowi/], under the Apache 2.0 License

package fr.upem.coursand.camera;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import fr.upem.coursand.R;

/**
 * An example of the use of Intent to launch the camera application to take pictures.
 * Note that this activity does not require any special permission since it does
 * not use directly the camera API.
 */
public class CameraCaller extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_camera_caller);
	}
	
	private final static int IMAGE_CAPTURE_REQUEST_CODE = 1;
	private final static int VIDEO_CAPTURE_REQUEST_CODE = 2;
	
	public void startCameraActivity(boolean video)
	{
		Intent intent = new Intent((video)?MediaStore.ACTION_VIDEO_CAPTURE:MediaStore.ACTION_IMAGE_CAPTURE);
		// We can also use MediaStore.ACTION_IMAGE_CAPTURE_SECURE to capture an image in lock mode
		// To capture a video, we use MediaStore.ACTION_VIDEO_CAPTURE
		File pictDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), this.getClass().getSimpleName());
		pictDir.mkdir();
		String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + (video ? ".mp4":".jpg");
		File dest = new File(pictDir, timestamp); // Destination file
		intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(dest)); // Specify the destination file
		// Now, we start the picture capture activity
		try {
			startActivityForResult(intent, (video) ? VIDEO_CAPTURE_REQUEST_CODE : IMAGE_CAPTURE_REQUEST_CODE);
		} catch (ActivityNotFoundException e)
		{
			Log.e(getClass().getName(), "Cannot start the activity due to an exception", e);
			Toast.makeText(this, "An exception encountered: " + e, Toast.LENGTH_SHORT).show();
		}
	}

	public void requestPicture(View v)
	{
		startCameraActivity(false);
	}

	public void requestVideo(View v)
	{
		startCameraActivity(true);
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		switch (requestCode)
		{
		case IMAGE_CAPTURE_REQUEST_CODE:
			switch (resultCode)
			{
			case RESULT_OK:
				Toast.makeText(this, "Image saved to " + data.getData(), Toast.LENGTH_LONG).show();
				// ((ImageView)findViewById(R.id.imageCaptureView)).setImageURI(data.getData());
				break;
			case RESULT_CANCELED: default:
				Toast.makeText(this, "Capture of image failed", Toast.LENGTH_SHORT).show();
			}
			break;
		case VIDEO_CAPTURE_REQUEST_CODE:
			switch (resultCode)
			{
			case RESULT_OK:
				Toast.makeText(this, "Video saved to " + data.getData(), Toast.LENGTH_LONG).show();
				break;
			case RESULT_CANCELED: default:
				Toast.makeText(this, "Capture of video failed", Toast.LENGTH_SHORT).show();
			}
		}
	}
}

Usage de l'API caméra

Ne pas oublier de rajouter dans le manifeste la permission d'usage de la caméra ainsi que les uses-feature :
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

Prévisualisation de caméra

Zoom et capture