MediaRecorder'a genel bakış

Android multimedya çerçevesi, çeşitli yaygın veri işleme yöntemlerinin ses ve video formatlarını kullanabilirsiniz. Destekleniyorsa MediaRecorder API'lerini kullanabilirsiniz cihaz donanımına göre değişir.

Bu dokümanda, bir cihazdan ses yakalayan bir uygulama yazmak için MediaRecorder özelliğinin nasıl kullanılacağı gösterilmektedir mikrofonu açabilir, sesi kaydedebilir ve oynatabilirsiniz (MediaPlayer ile). Video kaydetmek için gerekenler: MediaRecorder ile birlikte cihazın kamerasını kullanın. Bu konu, Kamera kılavuzunda açıklanmaktadır.

Not: Android Emulator kaydedemez ses'e dokunun. Kodunuzu, kayıt yapabilen gerçek bir cihazda test ettiğinizden emin olun.

Ses kaydetme izni isteniyor

Uygulamanızın kayıt yapabilmesi için, kullanıcıya cihazın ses girişine dokunun. Bu izin etiketini, uygulamanın manifest dosyasına eklemeniz gerekir:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

RECORD_AUDIO, "tehlikeli" izin çünkü kullanıcı gizliliği açısından risk teşkil edebilir. Android 6.0 (API düzeyi 23) sürümünden itibaren uygulama , tehlikeli bir izin kullanan kullanıcılardan çalışma zamanında onay istemelidir. Kullanıcı uygulama bunu hatırlamalı ve tekrar sormamalıdır. Aşağıdaki örnek kod, bu davranışı ActivityCompat.requestPermissions()

MediaRecorder oluşturma ve çalıştırma

Yeni bir MediaRecorder örneğini başlat aşağıdaki çağrılarla:

  • Ses kaynağını setAudioSource() Bir sonraki muhtemelen MIC kullanıyorsunuz.

    Not:Ses kaynaklarının çoğu (DEFAULT dahil) Ses sinyali. Ham ses kaydetmek için şunu seçin: UNPROCESSED Bazı cihazlar işlenmemiş işlemleri desteklemez giriş. Mevcut olduğunu doğrulamak için önce AudioManager.getProperty(AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED) numaralı telefonu arayın. Değilse VOICE_RECOGNITION seçeneğini kullanmayı deneyin. gürültü azaltma ya da AGC kullanmayan bir kampanya türüdür. UNPROCESSED kullanabilirsiniz desteklenmese bile ses kaynağı olarak gösterilebilir. Ancak sinyal işlenmez veya bu durumda işlenmez.

  • Çıkış dosyası biçimini setOutputFormat() MediaRecorder, Android 8.0 (API düzeyi 26) sürümünden itibaren MPEG2_TS biçimini destekler. biçimi vardır:

    Kotlin

    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS)
    

    Java

    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);
    
  • Çıkış dosyasının adını setOutputFile() Gerçek bir dosyayı temsil eden bir dosya tanımlayıcısı belirtmeniz gerekir.
  • Ses kodlayıcıyı setAudioEncoder()
  • Başlatma işlemini tamamlamak için şu numarayı arayın: prepare()

Şu numarayı arayarak kaydediciyi başlatın ve durdurun: start() ve stop() tıklayın.

MediaRecorder örneğiyle işiniz bittiğinde kaynaklarını serbest bırakın numaralı telefondan release().

Not: Android 9 (API düzeyi 28) veya arka planda çalışan uygulamalar mikrofona erişemez. Dolayısıyla, uygulamanız yalnızca ses ön planda çalışırken veya siz MediaRecorder örneğini ön plan hizmeti sunar.

Birden fazla kanal kaydetmek için MediaMuxer kullanma

Android 8.0 (API düzeyi 26) sürümünden itibaren MediaMuxer kullanabilirsiniz aynı anda birden fazla ses ve görüntü akışı kaydetme olanağı sunar. Android'in önceki sürümlerinde yalnızca aynı anda bir ses parçası ve/veya bir video parçası kaydedebilirsiniz.

addTrack() kullanın ve bu yöntemi kullanabilirsiniz.

Her kare için özel bilgiler içeren bir veya daha fazla meta veri parçası da ekleyebilirsiniz ancak veri yüklemelerine izin verir. Uygulamanız meta verilerin biçimini ve içeriğini tanımlar.

Meta veri ekleme

Meta veriler, çevrimdışı işleme için yararlı olabilir. Örneğin, jiroskop aracılığıyla video sabitleme özelliği kullanılabilir.

Bir meta veri parçası eklediğinizde parçanın MIME biçimi önekle başlamalıdır application/ Meta veri yazmak, video veya ses verilerini yazmakla aynıdır. Ancak bu işlem, verileri bir MediaCodec kaynağından gelmediğinden emin olun. Bunun yerine, uygulama ByteBuffer writeSampleData() yöntemini çağırın. Zaman damgası, video ve ses parçalarıyla aynı zaman tabanında olmalıdır.

Oluşturulan MP4 dosyası, 12.3.3.2 bölümünde tanımlanan TextMetaDataSampleEntry öğesini kullanır ISO BMFF spesifikasyonuna kullanabilirsiniz. Meta veri parçaları içeren bir dosyayı ayıklamak için MediaExtractor kullandığınızda meta verilerin mime'si biçimi, MediaFormat öğesinin bir örneği olarak görünür.

Örnek kod

MediaRecorder ornek, MediaRecorder ve Kamera API'sini kullanarak nasıl video kaydı yapılacağını göstermektedir.

Aşağıdaki örnek etkinlikte, ses dosyası kaydetmek için MediaRecorder yönteminin nasıl kullanılacağı gösterilmektedir. Google Sesi çalmak için de MediaPlayer kullanılır.

Kotlin

package com.android.audiorecordtest

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.media.MediaPlayer
import android.media.MediaRecorder
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.View.OnClickListener
import android.view.ViewGroup
import android.widget.Button
import android.widget.LinearLayout
import java.io.IOException

private const val LOG_TAG = "AudioRecordTest"
private const val REQUEST_RECORD_AUDIO_PERMISSION = 200

class AudioRecordTest : AppCompatActivity() {

    private var fileName: String = ""

    private var recordButton: RecordButton? = null
    private var recorder: MediaRecorder? = null

    private var playButton: PlayButton? = null
    private var player: MediaPlayer? = null

    // Requesting permission to RECORD_AUDIO
    private var permissionToRecordAccepted = false
    private var permissions: Array<String> = arrayOf(Manifest.permission.RECORD_AUDIO)

    override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<String>,
            grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        permissionToRecordAccepted = if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) {
            grantResults[0] == PackageManager.PERMISSION_GRANTED
        } else {
            false
        }
        if (!permissionToRecordAccepted) finish()
    }

    private fun onRecord(start: Boolean) = if (start) {
        startRecording()
    } else {
        stopRecording()
    }

    private fun onPlay(start: Boolean) = if (start) {
        startPlaying()
    } else {
        stopPlaying()
    }

    private fun startPlaying() {
        player = MediaPlayer().apply {
            try {
                setDataSource(fileName)
                prepare()
                start()
            } catch (e: IOException) {
                Log.e(LOG_TAG, "prepare() failed")
            }
        }
    }

    private fun stopPlaying() {
        player?.release()
        player = null
    }

    private fun startRecording() {
        recorder = MediaRecorder().apply {
            setAudioSource(MediaRecorder.AudioSource.MIC)
            setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
            setOutputFile(fileName)
            setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)

            try {
                prepare()
            } catch (e: IOException) {
                Log.e(LOG_TAG, "prepare() failed")
            }

            start()
        }
    }

    private fun stopRecording() {
        recorder?.apply {
            stop()
            release()
        }
        recorder = null
    }

    internal inner class RecordButton(ctx: Context) : Button(ctx) {

        var mStartRecording = true

        var clicker: OnClickListener = OnClickListener {
            onRecord(mStartRecording)
            text = when (mStartRecording) {
                true -> "Stop recording"
                false -> "Start recording"
            }
            mStartRecording = !mStartRecording
        }

        init {
            text = "Start recording"
            setOnClickListener(clicker)
        }
    }

    internal inner class PlayButton(ctx: Context) : Button(ctx) {
        var mStartPlaying = true
        var clicker: OnClickListener = OnClickListener {
            onPlay(mStartPlaying)
            text = when (mStartPlaying) {
                true -> "Stop playing"
                false -> "Start playing"
            }
            mStartPlaying = !mStartPlaying
        }

        init {
            text = "Start playing"
            setOnClickListener(clicker)
        }
    }

    override fun onCreate(icicle: Bundle?) {
        super.onCreate(icicle)

        // Record to the external cache directory for visibility
        fileName = "${externalCacheDir.absolutePath}/audiorecordtest.3gp"

        ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION)

        recordButton = RecordButton(this)
        playButton = PlayButton(this)
        val ll = LinearLayout(this).apply {
            addView(recordButton,
                    LinearLayout.LayoutParams(
                            ViewGroup.LayoutParams.WRAP_CONTENT,
                            ViewGroup.LayoutParams.WRAP_CONTENT,
                            0f))
            addView(playButton,
                    LinearLayout.LayoutParams(
                            ViewGroup.LayoutParams.WRAP_CONTENT,
                            ViewGroup.LayoutParams.WRAP_CONTENT,
                            0f))
        }
        setContentView(ll)
    }

    override fun onStop() {
        super.onStop()
        recorder?.release()
        recorder = null
        player?.release()
        player = null
    }
}

Java

package com.android.audiorecordtest;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;

import java.io.IOException;

public class AudioRecordTest extends AppCompatActivity {

    private static final String LOG_TAG = "AudioRecordTest";
    private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
    private static String fileName = null;

    private RecordButton recordButton = null;
    private MediaRecorder recorder = null;

    private PlayButton   playButton = null;
    private MediaPlayer   player = null;

    // Requesting permission to RECORD_AUDIO
    private boolean permissionToRecordAccepted = false;
    private String [] permissions = {Manifest.permission.RECORD_AUDIO};

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case REQUEST_RECORD_AUDIO_PERMISSION:
                permissionToRecordAccepted  = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                break;
        }
        if (!permissionToRecordAccepted ) finish();

    }

    private void onRecord(boolean start) {
        if (start) {
            startRecording();
        } else {
            stopRecording();
        }
    }

    private void onPlay(boolean start) {
        if (start) {
            startPlaying();
        } else {
            stopPlaying();
        }
    }

    private void startPlaying() {
        player = new MediaPlayer();
        try {
            player.setDataSource(fileName);
            player.prepare();
            player.start();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }
    }

    private void stopPlaying() {
        player.release();
        player = null;
    }

    private void startRecording() {
        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setOutputFile(fileName);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        try {
            recorder.prepare();
        } catch (IOException e) {
            Log.e(LOG_TAG, "prepare() failed");
        }

        recorder.start();
    }

    private void stopRecording() {
        recorder.stop();
        recorder.release();
        recorder = null;
    }

    class RecordButton extends Button {
        boolean mStartRecording = true;

        OnClickListener clicker = new OnClickListener() {
            public void onClick(View v) {
                onRecord(mStartRecording);
                if (mStartRecording) {
                    setText("Stop recording");
                } else {
                    setText("Start recording");
                }
                mStartRecording = !mStartRecording;
            }
        };

        public RecordButton(Context ctx) {
            super(ctx);
            setText("Start recording");
            setOnClickListener(clicker);
        }
    }

    class PlayButton extends Button {
        boolean mStartPlaying = true;

        OnClickListener clicker = new OnClickListener() {
            public void onClick(View v) {
                onPlay(mStartPlaying);
                if (mStartPlaying) {
                    setText("Stop playing");
                } else {
                    setText("Start playing");
                }
                mStartPlaying = !mStartPlaying;
            }
        };

        public PlayButton(Context ctx) {
            super(ctx);
            setText("Start playing");
            setOnClickListener(clicker);
        }
    }

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        // Record to the external cache directory for visibility
        fileName = getExternalCacheDir().getAbsolutePath();
        fileName += "/audiorecordtest.3gp";

        ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);

        LinearLayout ll = new LinearLayout(this);
        recordButton = new RecordButton(this);
        ll.addView(recordButton,
                new LinearLayout.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        0));
        playButton = new PlayButton(this);
        ll.addView(playButton,
                new LinearLayout.LayoutParams(
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        ViewGroup.LayoutParams.WRAP_CONTENT,
                        0));
        setContentView(ll);
    }

    @Override
    public void onStop() {
        super.onStop();
        if (recorder != null) {
            recorder.release();
            recorder = null;
        }

        if (player != null) {
            player.release();
            player = null;
        }
    }
}

Daha fazla bilgi

Bu sayfalarda, ses ve video kaydetme, depolama ve oynatmayla ilgili konular ele alınmaktadır.