Un po 'in ritardo, ma penso che questa sia una buona domanda e non ha ancora una buona risposta.
Se si desidera trasmettere in streaming telecamera e microfono da un dispositivo Android, esistono due alternative principali: implementazioni Java o NDK.
Implementazione Java.
Sto solo citando l'idea, ma fondamentalmente è implementare un server RTSP e protocollo RTP in Java sulla base di questi standard Real-Time Streaming Protocol Version 2.0 e RTP Payload Format for H.264 Video. Questo compito sarà molto lungo e difficile. Ma se stai facendo il tuo PhP potrebbe essere bello avere una buona lib di Java RTSP per Android.
Implementazione NDK.
Questa è un'alternativa comprende varie soluzioni. L'idea principale è usare una libreria C o C++ di potenza nella nostra applicazione Android. Per questa istanza, FFmpeg.Questa libreria può essere compilata per Android e può supportare varie architetture. Il problema di questo approccio è che potrebbe essere necessario conoscere l'NDK di Android, C e C++ per realizzare questo.
Ma c'è un'alternativa. Puoi racchiudere la libreria c e usare FFmpeg. Ma come?
Ad esempio, utilizzando FFmpeg Android, che è stato compilato con x264, libass, fontconfig, freetype e fribidi e supporta varie architetture. Ma è ancora difficile programmare se si desidera eseguire lo streaming in tempo reale è necessario gestire i descrittori di file e i flussi in/out.
L'alternativa migliore, dal punto di vista della programmazione Java, è l'utilizzo di JavaCV. JavaCV utilizza involucri da librerie comunemente usati di computer vision che comprende: (OpenCV, FFmpeg, ecc, e fornisce classi di utilità per rendere la loro funzionalità più facile da utilizzare sulla piattaforma Java, tra cui (ovviamente) Android
JavaCV viene inoltre fornito. con visualizzazione hardware a schermo intero accelerato (CanvasFrame
e GLCanvasFrame
), metodi facili da usare per eseguire codice in parallelo su più core (Parallel
), calibrazione geometrica e cromatica facile da usare di videocamere e proiettori (GeometricCalibrator
, ProCamGeometricCalibrator
, ProCamColorCalibrator
) , rilevamento e corrispondenza dei punti funzione (ObjectFinder
), un insieme di classi che implementano l'allineamento diretto dell'immagine dei sistemi di videoproiettori (principalmente GNImageAligner
, ProjectiveTransformer
, ProjectiveColorTransformer
, ProCamTransformer
e ReflectanceInitializer
), un pacchetto di analisi BLOB (Blobs
) e varie funzionalità nella classe JavaCV
. Alcune di queste classi hanno anche un omologo OpenCL e OpenGL, i loro nomi che terminano con CL
o che iniziano con GL
, cioè .: JavaCVCL
, GLCanvasFrame
, ecc
Ma come possiamo usare questa soluzione?
Qui abbiamo un'implementazione di base per lo streaming utilizzando UDP.
String streamURL = "udp://ip_destination:port";
recorder = new FFmpegFrameRecorder(streamURL, frameWidth, frameHeight, 1);
recorder.setInterleaved(false);
// video options //
recorder.setFormat("mpegts");
recorder.setVideoOption("tune", "zerolatency");
recorder.setVideoOption("preset", "ultrafast");
recorder.setVideoBitrate(5 * 1024 * 1024);
recorder.setFrameRate(30);
recorder.setSampleRate(AUDIO_SAMPLE_RATE);
recorder.setVideoCodec(AV_CODEC_ID_H264);
recorder.setAudioCodec(AV_CODEC_ID_AAC);
Questa parte del codice mostra come inizializzare l'oggetto FFmpegFrameRecorder chiamato registratore. Questo oggetto catturerà e codificherà i fotogrammi ottenuti dalla fotocamera e i campioni ottenuti dal microfono.
Se si desidera acquisire un'anteprima nella stessa app Android, è necessario implementare una classe CameraPreview questa classe convertirà i dati grezzi forniti dalla fotocamera e creerà l'anteprima e il fotogramma per FFmpegFrameRecorder.
Ricordarsi di sostituire ip_destination con l'ip del pc o del dispositivo in cui si desidera inviare lo streaming. La porta può essere 8080 come esempio.
@Override
public Mat onCameraFrame(Mat mat)
{
if (audioRecordRunnable == null) {
startTime = System.currentTimeMillis();
return mat;
}
if (recording && mat != null) {
synchronized (semaphore) {
try {
Frame frame = converterToMat.convert(mat);
long t = 1000 * (System.currentTimeMillis() - startTime);
if (t > recorder.getTimestamp()) {
recorder.setTimestamp(t);
}
recorder.record(frame);
} catch (FFmpegFrameRecorder.Exception e) {
LogHelper.i(TAG, e.getMessage());
e.printStackTrace();
}
}
}
return mat;
}
Questo metodo mostra l'implementazione del metodo onCameraFrame
che supporta l'Mat (foto) dalla fotocamera e viene convertito in frame e registrati dall'oggetto FFmpegFrameRecorder.
@Override
public void onSampleReady(ShortBuffer audioData)
{
if (recorder == null) return;
if (recording && audioData == null) return;
try {
long t = 1000 * (System.currentTimeMillis() - startTime);
if (t > recorder.getTimestamp()) {
recorder.setTimestamp(t);
}
LogHelper.e(TAG, "audioData: " + audioData);
recorder.recordSamples(audioData);
} catch (FFmpegFrameRecorder.Exception e) {
LogHelper.v(TAG, e.getMessage());
e.printStackTrace();
}
}
stessa con l'audio audioData
è un oggetto ShortBuffer
che sarà registratore dal FFmpegFrameRecorder.
Nella destinazione del PC o del dispositivo è possibile eseguire il seguente comando per ottenere lo streaming.
ffplay udp://ip_source:port
Il ip_source
è l'IP dello smartphone che è in streaming la fotocamera e microfono torrente. La porta deve essere la stessa 8080.
Ho creato una soluzione nel mio repository github qui: UDPAVStreamer.
Buona fortuna
perché stai decodifica usando ffmpeg? utilizzare l'oggetto MediaPlayer incorporato –
Hai provato a utilizzare live555 per trasmettere l'output di ffmpeg tramite RTSP? Inoltre, ffmpeg non dovrebbe sondare il flusso e trovare informazioni sul flusso stesso? – Shark
Penso che Aviad abbia la verità. Come fai a sapere quale formato video produce la fotocamera? –