In exoplayer, how to play buffered bytes from inputstram as a video? - android

I am downloading an mp4 video into a local disk drive from an intranet as the following:
while ((bufferLength = inputstram.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, bufferLength);
//play(buffer);
downloadedSize += bufferLength;
System.out.println("remaining: " + downloadedSize + " out of " + totalSize);
}
While downloading (after fileOutputStream.write(buffer, 0, bufferLength); statement), I need to play the downloaded buffers in the while loop in exoplayer. How can I do that? I was searching in google and into exoplayer docs but I couldn't find a straight forward answer.
At the moment, I am playing a video in exoplayer as a URL as the following code:
MediaSource videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse("http://myhappy_video.mp4"));
So how can I change that to play buffered bytes from input stream as a video?

To play a video from http server. You can use DefaultHttpDataSource with DashMediaSource. The following is an example.
// Create a data source factory.
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
// Create a DASH media source pointing to a DASH manifest uri.
MediaSource mediaSource =
new DashMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(dashUri));
// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media source to be played.
player.setMediaSource(mediaSource);
// Prepare the player.
player.prepare();

Related

Is it possible to play a rtmp livestream in android app

Does anyone know if it’s possible to play a rtmp stream with exoplayer.
I’ve tried this but didn’t manage to get it working:
ExoPlayer player = new ExoPlayer.Builder(this).build();
playerView.setPlayer(player);
Uri uri = Uri.parse("rtmp://192.168.109.84/live");
MediaItem mediaItem = MediaItem.fromUri(uri);
RtmpDataSource.Factory rtmpDataSourceFactory = new RtmpDataSource.Factory();
MediaSource mediaSource = new ProgressiveMediaSource.Factory(rtmpDataSourceFactory).createMediaSource(mediaItem);
player.setMediaSource(mediaSource);
player.prepare();
player.setPlayWhenReady(true);

Android AudioRecord pcm16bit WAV files - can't be played externally?

I created a WAV file based from https://developer.xamarin.com/samples/monodroid/Example_WorkingWithAudio/ where the relevant code are as follows:
private const int RECORDER_SAMPLERATE = 16000;
private const ChannelIn RECORDER_CHANNELS = ChannelIn.Mono;
private const Android.Media.Encoding RECORDER_AUDIO_ENCODING = Android.Media.Encoding.Pcm16bit;
...
var bufferSize = AudioRecord.GetMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);
audioBuffer = new byte[bufferSize];
audioRecord = new AudioRecord(
// Hardware source of recording.
AudioSource.Mic,
// Frequency
RECORDER_SAMPLERATE,
// Mono or stereo
RECORDER_CHANNELS,
// Audio encoding
RECORDER_AUDIO_ENCODING,
// Length of the audio clip.
audioBuffer.Length
);
audioRecord.StartRecording();
...
using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
while (true)
{
if (endRecording)
{
endRecording = false;
break;
}
try
{
// Keep reading the buffer while there is audio input.
int numBytes = await audioRecord.ReadAsync(audioBuffer, 0, audioBuffer.Length);
await fileStream.WriteAsync(audioBuffer, 0, numBytes);
// Do something with the audio input.
}
catch (Exception ex)
{
Console.Out.WriteLine(ex.Message);
break;
}
}
fileStream.Close();
}
audioRecord.Stop();
audioRecord.Release();
My question is - how can I play this .WAV file after copying in Windows (or other OS)? Here are my observations:
.WAV file can be played using Android's AudioTrack class, as shown in the https://developer.xamarin.com/samples/monodroid/Example_WorkingWithAudio/ code sample.
The code sample will create a testAudio.wav file in the /data/Example_WorkingWithAudio/files/ directory.
Try to copy this file to your Windows PC, then try playing the .WAV file with an audio player which supports .WAV. See that it won't be able to play the file.
to revert back, I found out that the created track needs to be converted to .WAV first. Here are 2 posts which helped me do it.
http://www.edumobile.org/android/audio-recording-in-wav-format-in-android-programming/
Recorded audio Using AndroidRecord API fails to play

How to play streaming audio using mms protocol

I want to record audio from webserver using mms protocol on android phone.
present, I'm record streaming audio.
But, I can't seek while play recorded audio.
If you know record and play streaming audio using mms protocol, please let me know.
Important, while play recorded audio, user can seek with seekbar.
URL url = new URL("http://myradio,com/stream.mp3");
inputStream = url.openStream();
Log.d(LOG_TAG, "url.openStream()");
fileOutputStream = new FileOutputStream(outputSource);
Log.d(LOG_TAG, "FileOutputStream: " + outputSource);
int c;
while ((c = inputStream.read()) != -1) {
Log.d(LOG_TAG, "bytesRead=" + bytesRead);
fileOutputStream.write(c);
bytesRead++;
}
or go to this

Android: How to record mp3 radio (audio) stream

My favorite Radio station plays a radio audio stream in mp3 format. In my android application I can receive and play it without any problem.
How can I implement a recording function? I want to record the mp3 radio stream to my Android phones SD-Card.
I tried the MediaRecorder Class without any result...
Android Developer: MediaRecorder
...
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
...
Unfortunately I cannot choose something like:
mRecorder.setAudioSource(MediaRecorder.AudioSource.MP3_STREAM); ... ;-)
How can I record a mp3 radio stream? Thanks for any help or code snippets...
Perfect! Reading the audio stream "byte by byte" is the solution. Thank you!!
Here my code snippets:
URL url = new URL("http://myradio,com/stream.mp3");
inputStream = url.openStream();
Log.d(LOG_TAG, "url.openStream()");
fileOutputStream = new FileOutputStream(outputSource);
Log.d(LOG_TAG, "FileOutputStream: " + outputSource);
int c;
while ((c = inputStream.read()) != -1) {
Log.d(LOG_TAG, "bytesRead=" + bytesRead);
fileOutputStream.write(c);
bytesRead++;
}
Maybe you should read audio stream "byte by byte" and then place it into new file? Like a simple file copy operation, using inputstream-outputstream.

Streaming AAC audio with Android

As I understand it, Android will only play AAC format audio if it's encoded as MPEG-4 or 3GPP.
I'm able to play AAC audio encoded as M4A when it's local to the app, but it fails when obtaining it from a server.
The following works, as the m4a file is held locally in the res/raw directory.
MediaPlayer mp = MediaPlayer.create(this, R.raw.*file*);
mp.start();
The following doesn't work. (But does with MP3's).
Uri uri = Uri.parse("http://*example.com*/blah.m4a");
MediaPlayer mp = MediaPlayer.create(this, uri);
mp.start();
Can anyone shed any light on why it fails when the m4a audio file is not local?
Here's (some of) the error...
ERROR/PlayerDriver(542): Command PLAYER_INIT completed with an error or info UNKNOWN PVMFStatus
ERROR/MediaPlayer(769): error (200, -32)
WARN/PlayerDriver(542): PVMFInfoErrorHandlingComplete
DEBUG/MediaPlayer(769): create failed:
DEBUG/MediaPlayer(769): java.io.IOException: Prepare failed.: status=0xC8
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.prepare(Native Method)
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.create(MediaPlayer.java:530)
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.create(MediaPlayer.java:507)
...
I'm targeting SDK 1.6.
This work-around allows you to play M4A files from the net (and AAC files in other containers such as MP4 & 3GP). It simply downloads the file and plays from the cache.
private File mediaFile;
private void playAudio(String mediaUrl) {
try {
URLConnection cn = new URL(mediaUrl).openConnection();
InputStream is = cn.getInputStream();
// create file to store audio
mediaFile = new File(this.getCacheDir(),"mediafile");
FileOutputStream fos = new FileOutputStream(mediaFile);
byte buf[] = new byte[16 * 1024];
Log.i("FileOutputStream", "Download");
// write to file until complete
do {
int numread = is.read(buf);
if (numread <= 0)
break;
fos.write(buf, 0, numread);
} while (true);
fos.flush();
fos.close();
Log.i("FileOutputStream", "Saved");
MediaPlayer mp = new MediaPlayer();
// create listener to tidy up after playback complete
MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// free up media player
mp.release();
Log.i("MediaPlayer.OnCompletionListener", "MediaPlayer Released");
}
};
mp.setOnCompletionListener(listener);
FileInputStream fis = new FileInputStream(mediaFile);
// set mediaplayer data source to file descriptor of input stream
mp.setDataSource(fis.getFD());
mp.prepare();
Log.i("MediaPlayer", "Start Player");
mp.start();
} catch (Exception e) {
e.printStackTrace();
}
}
I tried it too but I could not find out the solution!
At the last Google I/O I saw something that helped me a lot. It is Extending from MediaPlayer and improve a lot of things! Take a look.
EXOPLAYER CAN HELP YOU A LOT
Check this part of the example:
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
private static final int BUFFER_SEGMENT_COUNT = 256;
...
// String with the url of the radio you want to play
String url = getRadioUrl();
Uri radioUri = Uri.parse(url);
// Settings for exoPlayer
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
String userAgent = Util.getUserAgent(context, "ExoPlayerDemo");
DataSource dataSource = new DefaultUriDataSource(context, null, userAgent);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
radioUri, dataSource, allocator, BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT);
audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
// Prepare ExoPlayer
exoPlayer.prepare(audioRenderer);
EXOPLAYER- I can play anything from streamings (video and audio)!
LET ME KNOW IF YOU NEED HELP TO IMPLEMENT IT! :)
This is a wild shot in the dark, but I have seen similar behavior with the flash player where it actually ignores the file name and only relies on the MIME type sent by the server. Any idea what headers are being sent down from example.com? You might want to try wrapping your blah.m4a in a page that can set the headers and then stream the binary data. Give these types a shot and the community would appreciate a confirmation of what works:
audio/mpeg
audio/mp4a
audio/mp4a-latm
audio/aac
audio/x-aac
I found that if you record the audio file on Android with the following properties, you are then able to play it on your server. It also plays well in the HTML Audio Element, however only on Firefox at the moment. This may change in the future.
Android (JAVA):
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioChannels(1);
mediaRecorder.setOutputFile(filePath);
HTML:
<audio id="audioMediaControl" controls src="yourfile.m4a"> Your browser does not support the audio element. </audio>
try --
1) MP.prepareAsync()
2) onPrepared() { mp.start() }

Categories

Resources