2009-06-23 15 views
21

Chciałbym stworzyć magnetowid i jak dotąd nie zorientowałem się, jak ustawić parametry, aby pomyślnie przejść przez MediaRecorder.prepare() metoda.Android: Czy ktoś wie, jak przechwytywać wideo?

wykonując następujące metody

public void start() throws IOException{ 
    String state = android.os.Environment.getExternalStorageState(); 
    if(!state.equals(Environment.MEDIA_MOUNTED)) 
    { 
     throw new IOException("SD card is not mounted. It is " + state + "."); 
    } 
    File directory = new File(path).getParentFile(); 
    if(!directory.exists() && !directory.mkdirs()) 
    { 
     throw new IOException("Path to file could not be created."); 
    } 

    recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
    recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
    recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); 
    recorder.setVideoFrameRate(15); 
    recorder.setVideoSize(176, 144); 
    recorder.setOutputFile(path); 
    recorder.prepare(); 
    recorder.start(); 
    this.state = VideoRecorderState.STATE_RECORDING; 
} 

zgłasza wyjątek na linii recorder.prepare().

Czy ktoś wie jak ustawić parametry, aby być w stanie przechwytywać wideo?

Dzięki!

+0

Nie wiem, ale czuję się dla ciebie. Właśnie wydostałem się z J2ME w tym obszarze. Co najmniej dziwne! –

+3

Jaki jest wyjątek? –

Odpowiedz

2

Być może aplikacja aparatu source pomaga w debugowaniu tego.

1

Może to być błąd uprawnień. Czy masz uprawnienia Android.permission.CAMERA w swoim pliku AndroidManifest?

13

Oto fragment, który działa:

m_recorder = new MediaRecorder(); 
m_recorder.setPreviewDisplay(m_BeMeSurface); 
m_recorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
m_recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); 
m_recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
m_recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
m_recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP); 
m_recorder.setMaxDuration((int) MAX_TIME); 
m_recorder.setOnInfoListener(m_BeMeSelf); 
m_recorder.setVideoSize(320, 240); 
m_recorder.setVideoFrameRate(15); 
m_recorder.setOutputFile(m_path); 

m_recorder.prepare(); 
m_recorder.start(); 

Najważniejszą rzeczą jest powierzchnia. Nie masz go, więc bez niego zawodzi.

Pozdrowienia

BeMeCollective

+1

Zadałem pytanie dotyczące wymagania powierzchni. –

2

Czy to wyrejestrowany?

http://code.google.com/p/android/issues/detail?id=5050

Oni sugerują, że jest to problem rozrządu, i że maszyna stanu MediaRecorder może wymagać pewnego opóźnienia (sprzęt zależna?) Pomiędzy państwami.

Byłoby miło, gdyby pojawiły się wywołania zwrotne, kiedy każdy stan został w pełni osiągnięty - wtedy moglibyśmy po prostu przygotować się do tego.

0

W moim przypadku kopiowanie i wklejanie powyższych próbek nie działało. Następnie, przeglądając metody w MediaRecorder, znalazłem setPreviewDisplay. Wywołałem tę metodę przechodząc przez powierzchnię używaną w Camera.setPreviewDisplay, uniknięto IOException w .prepare i udało mi się nagrać wideo. Spróbuj samodzielnie i opublikuj swoje wyniki.

4

Miałem to samo pytanie. Chodziłem od usługi nagrywania dźwięku w tle i miałem nadzieję, że utworzę usługę nagrywania wideo w tle. Nie możesz naprawdę nagrać wideo w tle, ale możesz zrobić bardzo mały podgląd wideo w istniejącym interfejsie użytkownika. Poszedłem za tutorialem: http://integratingstuff.wordpress.com/2010/10/18/writing-code-that-captures-videos-on-android/ i przykładową prezentacją Podglądu kamery. Ale ostatecznie przykładowy kod w http://www.apress.com/downloadable/download/sample/sample_id/39/ był na tyle prosty, że można go było naśladować, ale także wystarczająco kompletny, by pracować z setCamera. Opublikuję tutaj moje rozwiązanie, aby zaoszczędzić innym czas w ich rozwoju od przykładów zabawek, do złożonego przykładu z dobrą jakością nagrywania wideo w tle (w razie potrzeby za pomocą kamery przedniej).

To jest źródło dla nagrywarki wideo z systemem Android z podglądem "nie" (podgląd to piksel 1x1, który symuluje dyskretną diodę nagrywania), do nagrywania wideo bez rozpraszania uwagi użytkowników. Aby użyć własnego interfejsu użytkownika, po prostu zmień plik video_recorder.xml na swój układ (pamiętaj o zachowaniu VideoView). Został przetestowany na urządzeniach z Androidem 2.2 i 3.0.

Odpowiednie przypadki użycia:

  • oko wzrok śledzenie biblioteki, aby umożliwić użytkownikom korzystać oczy jak mysz do nawigacji strony sieci Web
  • użycie tabletu aparatu (ów) aby zastąpić kamerę wideo w eksperymentach laboratoryjnych/Klinika (psycholingusitics lub patologii mowy)

Układ XML:

<?xml version="1.0" encoding="utf-8"?> 
<!-- This file is /res/layout/video_recorder.xml based on listing 9-6 in Pro Android 2 --> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:orientation="vertical" android:layout_width="fill_parent" 
     android:layout_height="fill_parent"> 

    <RelativeLayout android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:gravity="center"> 

      <VideoView android:id="@+id/videoView" android:layout_width="1px" 
        android:layout_height="1px" /> 

    </RelativeLayout> 
</LinearLayout> 

Klasa Java:

import java.io.File; 
import android.app.Activity; 
import android.hardware.Camera; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.MotionEvent; 
import android.view.SurfaceHolder; 
import android.widget.Toast; 
import android.widget.VideoView; 
/** 
* Android video recorder with "no" preview (the preview is a 1x1 pixel which 
* simulates an unobtrusive recording led). Based on Pro Android 2 2010 (Hashimi 
* et al) source code in Listing 9-6. 
* 
* Also demonstrates how to use the front-facing and back-facing cameras. 
* A calling Intent can pass an Extra to use the front facing camera if available. 
* 
* Suitable use cases: 
* A: eye gaze tracking library to let users use eyes as a mouse to navigate a web page 
* B: use tablet camera(s) to replace video camera in lab experiments 
* (psycholingusitics or other experiments) 
* 
* Video is recording is controlled in two ways: 
* 1. Video starts and stops with the activity 
* 2. Video starts and stops on any touch 
* 
* To control recording in other ways see the try blocks of the onTouchEvent 
* 
* To incorporate into project add these features and permissions to 
* manifest.xml: 
* 
* <uses-feature android:name="android.hardware.camera"/> 
* <uses-feature android:name="android.hardware.camera.autofocus"/> 
* 
* <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
* <uses-permission android:name="android.permission.CAMERA" /> 
* <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
* 
* Tested Date: October 2 2011 with manifest.xml 
* <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/> 
*/ 
public class VideoRecorderSubExperiment extends Activity implements 
     SurfaceHolder.Callback { 
    public static final String EXTRA_USE_FRONT_FACING_CAMERA ="frontcamera"; 
    private static final String OUTPUT_FILE = "/sdcard/videooutput"; 
    private static final String TAG = "RecordVideo"; 
    private Boolean mRecording = false; 
    private Boolean mUseFrontFacingCamera = false; 
    private VideoView mVideoView = null; 
    private MediaRecorder mVideoRecorder = null; 
    private Camera mCamera; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.video_recorder); 
     mVideoView = (VideoView) this.findViewById(R.id.videoView); 

     //mUseFrontFacingCamera = getIntent().getExtras().getBoolean(
     //  EXTRA_USE_FRONT_FACING_CAMERA, true); 
     if(mUseFrontFacingCamera){ 
      // If caller wants to use front facing camera, then make sure the device has one... 
      // Hard coded to only open front facing camera on Xoom (model MZ604) 
      // For more universal solution try: 
      // http://stackoverflow.com/questions/2779002/how-to-open-front-camera-on-android-platform 
      String deviceModel = android.os.Build.MODEL; 
      if (deviceModel.contains("MZ604")) { 
       mUseFrontFacingCamera = true; 
      } else { 
       Toast.makeText(
         getApplicationContext(), 
         "The App isn't designed to use this Android's front facing camera.\n " + 
         "The device model is : " + deviceModel, Toast.LENGTH_LONG).show(); 
       mUseFrontFacingCamera = false; 
      } 
     } 

     final SurfaceHolder holder = mVideoView.getHolder(); 
     holder.addCallback(this); 
     holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    public boolean onTouchEvent(MotionEvent event) { 
     // can use the xy of the touch to start and stop recording 
     float positionX = event.getX(); 
     float positionY = event.getY(); 

     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      // Screen is pressed for the first time 
      break; 
     case MotionEvent.ACTION_MOVE: 
      // Screen is still pressed, float have been updated 
      break; 
     case MotionEvent.ACTION_UP: 
      // Screen is not touched anymore 
      if (mRecording) { 
       // To stop recording attach this try block to another event listener, 
       // button etc 
       try { 
        stopRecording(); 
       } catch (Exception e) { 
        Log.e(TAG, e.toString()); 
        e.printStackTrace(); 
       } 
      } else { 
       // To begin recording attach this try block to another event listener, 
       // button etc 
       try { 
        beginRecording(mVideoView.getHolder()); 
       } catch (Exception e) { 
        Log.e(TAG, e.toString()); 
        e.printStackTrace(); 
       } 
      } 
      break; 
     } 
     return super.onTouchEvent(event); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     try { 
      beginRecording(holder); 
     } catch (Exception e) { 
      Log.e(TAG, e.toString()); 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, 
      int height) { 
     Log.v(TAG, "Width x Height = " + width + "x" + height); 
    } 

    private void stopRecording() throws Exception { 
     mRecording = false; 
     if (mVideoRecorder != null) { 
      mVideoRecorder.stop(); 
      mVideoRecorder.release(); 
      mVideoRecorder = null; 
     } 
     if (mCamera != null) { 
      mCamera.reconnect(); 
      mCamera.stopPreview(); 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     try { 
      stopRecording(); 
     } catch (Exception e) { 
      Log.e(TAG, e.toString()); 
      e.printStackTrace(); 
     } 
     super.onDestroy(); 

    } 

    /** 
    * Uses the surface defined in video_recorder.xml 
    * Tested using 
    * 2.2 (HTC Desire/Hero phone) -> Use all defaults works, records back facing camera with AMR_NB audio 
    * 3.0 (Motorola Xoom tablet) -> Use all defaults doesn't work, works with these specs, might work with others 
    * 
    * @param holder The surfaceholder from the videoview of the layout 
    * @throws Exception 
    */ 
    private void beginRecording(SurfaceHolder holder) throws Exception { 
     if (mVideoRecorder != null) { 
      mVideoRecorder.stop(); 
      mVideoRecorder.release(); 
      mVideoRecorder = null; 
     } 
     if (mCamera != null) { 
      mCamera.reconnect(); 
      mCamera.stopPreview(); 
      mCamera.release(); 
      mCamera = null; 
     } 

     String uniqueOutFile = OUTPUT_FILE + System.currentTimeMillis() + ".3gp"; 
     File outFile = new File(uniqueOutFile); 
     if (outFile.exists()) { 
      outFile.delete(); 
     } 

     try { 
      if (mUseFrontFacingCamera) { 
       //hard coded assuming 1 is the front facing camera 
       mCamera = Camera.open(1); 
      } else { 
       mCamera = Camera.open(); 
      } 

      // Camera setup is based on the API Camera Preview demo 
      mCamera.setPreviewDisplay(holder); 
      Camera.Parameters parameters = mCamera.getParameters(); 
      parameters.setPreviewSize(640, 480); 
      mCamera.setParameters(parameters); 
      mCamera.startPreview(); 
      mCamera.unlock(); 

      mVideoRecorder = new MediaRecorder(); 
      mVideoRecorder.setCamera(mCamera); 

      // Media recorder setup is based on Listing 9-6, Hashimi et all 2010 
      // values based on best practices and good quality, 
      // tested via upload to YouTube and played in QuickTime on Mac Snow Leopard 
      mVideoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); 
      mVideoRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
      mVideoRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);// THREE_GPP 
                                      // is big-endian, 
                                      // storing and 
                                      // transferring 
                                      // the most 
                                      // significant 
                                      // bytes first. 
                                      // MPEG_4 as another option 
      mVideoRecorder.setVideoSize(640, 480);// YouTube recommended size: 320x240, 
                      // OpenGazer eye tracker: 640x480 
                      // YouTube HD: 1280x720 
      mVideoRecorder.setVideoFrameRate(20); //might be auto-determined due to lighting 
      mVideoRecorder.setVideoEncodingBitRate(3000000);// 3 megapixel, or the max of 
                           // the camera 
      mVideoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// MPEG_4_SP 
                                   // Simple Profile is 
                                   // for low bit 
                                   // rate and low 
                                   // resolution 
                                   // H264 is MPEG-4 Part 10 
                                   //is commonly referred to 
                                   // as H.264 or AVC 
      int sdk = android.os.Build.VERSION.SDK_INT; 
      // Gingerbread and up can have wide band ie 16,000 hz recordings 
      // (Okay quality for human voice) 
      if (sdk >= 10) { 
       mVideoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_WB); 
       mVideoRecorder.setAudioSamplingRate(16000); 
      } else { 
       // Other devices only have narrow band, ie 8,000 hz 
       // (Same quality as a phone call, not really good quality for any purpose. 
       // For human voice 8,000 hz means /f/ and /th/ are indistinguishable) 
       mVideoRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 
      } 
      mVideoRecorder.setMaxDuration(30000); // limit to 30 seconds 
      mVideoRecorder.setPreviewDisplay(holder.getSurface()); 
      mVideoRecorder.setOutputFile(uniqueOutFile); 
      mVideoRecorder.prepare(); 
      mVideoRecorder.start(); 
      mRecording = true; 
     } catch (Exception e) { 
      Log.e(TAG, e.toString()); 
      e.printStackTrace(); 
     } 
    } 
} 
+0

kod, który opublikowałeś, chciałbym skomentować 'mUseFrontFacingCamera = getIntent(). GetExtras(). GetBoolean ( EXTRA_USE_FRONT_FACING_CAMERA, true); 'aby działało. Testowane na SGS2 ICS 4.0.3 i Samsung Tablet GTP1000 na 2.3.6. Tks do dzielenia się, 1up. –

+0

zrobione. dzięki @Tuga! – cesine

+0

To jest najlepszy kod, jaki udało mi się znaleźć. Z wyjątkiem jednego problemu. Kiedy zadzwonię do niego z zakodowaną rozdzielczością, działa idealnie. Ale muszę to nazwać metodą i przekazać inną rozdzielczość za każdym razem, gdy zacznie się od użytkownika. Kiedy nazywam go różnymi rozdzielczościami, daje mi to błąd: 'start nie powiódł się: -19' -' 06-28 19: 41: 07.338: E/MediaRecorder (25092): spróbuj usunąć uszkodzony plik:/storage/sdcard0/Chimp_0160/recording.3gp' –

Powiązane problemy