How to decrease the latency of the RTP streaming with ffmpeg in Android?

How to decrease the latency of the RTP streaming with ffmpeg in Android?



I'm creating a App that do a RTP streaming. It uses a ParcelFileDescriptor pipe pair, where a MediaRecorder writes in the pipe while the ffmpeg receives the audio from the pipe and sends by RTP.



In my desktop, using the same wifi router, I receive the RTP stream using ffplay, and it has a delay between 5s ~ 10s.



I tried capture audio using ffmpeg in Android, but itsn't possible. I tried to use ffplay -fflags nobuffer, use MIC as source, change the encoder, etc.



I need the lowest delay possible. How can I do it?



The code:


public class MainActivity extends AppCompatActivity implements View.OnClickListener
MediaRecorder mediaRecorder;
AudioRecord record;
MediaPlayer mediaPlayer;
ParcelFileDescriptor pipePair;
ParcelFileDescriptor pipeRead;
ParcelFileDescriptor pipeWrite;
Process ffmpegProc;
// Requesting permission to RECORD_AUDIO
private boolean permissionsAccepted = false;
private String permissions =
Manifest.permission.RECORD_AUDIO,
Manifest.permission.INTERNET,
Manifest.permission.ACCESS_NETWORK_STATE
;
private static final int REQUEST_PERMISSIONS = 200;

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions, @NonNull int grantResults)
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode)
case REQUEST_PERMISSIONS:
permissionsAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;

if (!permissionsAccepted ) finish();



@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(this, permissions, REQUEST_PERMISSIONS);

TextView hello = (TextView) findViewById(R.id.hello);
hello.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Toast.makeText(MainActivity.this, "Clicado",Toast.LENGTH_SHORT)
.show();
copiarFFMpeg();


);



private void executarFFMpeg(final String cmd, ParcelFileDescriptor read)

try
ffmpegProc = Runtime.getRuntime().exec(cmd);
catch (IOException e)
e.printStackTrace();


(new Thread(new Runnable()
@Override
public void run()
try
InputStream inStream = ffmpegProc.getInputStream();
InputStreamReader sReader = new InputStreamReader(inStream);
BufferedReader bufferedReader = new BufferedReader(sReader);
String line;
while ((line = bufferedReader.readLine()) != null)
Log.d("FFMPEG",line);

catch (IOException e)
e.printStackTrace();


)).start();

(new Thread(new Runnable()
@Override
public void run()
byte buffer = new byte[8192];
int read = 0;

OutputStream ffmpegInput = ffmpegProc.getOutputStream();
FileInputStream reader = new FileInputStream(pipeRead.getFileDescriptor());

try

while (true)

if (reader.available()>0)
read = reader.read(buffer);
ffmpegInput.write(buffer, 0, read);
ffmpegInput.flush();
else
Thread.sleep(10);




catch (InterruptedException e)
e.printStackTrace();

catch (IOException e)
e.printStackTrace();

onDestroy();


)).start();

Log.d("FFMPEG","Executado");


private boolean estaExecutando(Process ffmpegProc)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
return ffmpegProc.isAlive();
else
try
ffmpegProc.exitValue();
return false;
catch (Exception e)
return true;




private void criarMediaRecorder()
if (pipeWrite != null)
try
//ffplay.exe -protocol_whitelist rtp,file,udp ..file.sdp
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
//mediaRecorder.setAudioChannels(2);
mediaRecorder.setOutputFile(pipeWrite.getFileDescriptor());
mediaRecorder.prepare();
mediaRecorder.start();
Log.d("MREC","MediaRecorder criado");
catch (Exception e)
e.printStackTrace();




private void criarPipe()
try
pipePair =ParcelFileDescriptor.createPipe();
catch (IOException e)
Log.e("PIPE","Deu zica na criação do pipe");
e.printStackTrace();
finish();

pipeRead = new ParcelFileDescriptor(pipePair[0]);
pipeWrite = new ParcelFileDescriptor(pipePair[1]);


private void copiarFFMpeg()
FFmpeg ffmpeg = FFmpeg.getInstance(this);
try
ffmpeg.loadBinary(new LoadBinaryResponseHandler()

@Override
public void onStart()
Log.d("FFMPEG","Iniciar cópia");


@Override
public void onFailure()
Log.e("FFMPEG","Cópia falhou");


@Override
public void onSuccess()
Log.d("FFMPEG","Cópiado com sucesso");

criarPipe();
//mediaRecorder.start();
File ffmpegBin = new File(getFilesDir().getAbsolutePath()+"/ffmpeg");
String cmd = new String
ffmpegBin.getAbsolutePath(),
"-re",
"-thread_queue_size","4",
"-i","pipe:",
//"-c:a","libx264",
//"-preset","veryfast",
//"-tune","zerolatency",
"-f",
"rtp",
"rtp://192.168.0.33:1234"
;

executarFFMpeg(cmd, pipeRead);

criarMediaRecorder();


@Override
public void onFinish()

);
catch (FFmpegNotSupportedException e)
// Handle if FFmpeg is not supported by device
Log.e("FFMPEG", "Não sou suportado :/");



@Override
protected void onDestroy()
super.onDestroy();


@Override
public void onClick(View view)





The command:


ffplay rtp://192.168.0.33:1234

ffplay -fflags nobuffer rtp://192.168.0.33:1234









By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)