2
votes

I am creating a mobile application that does the following

  • Record a *.mp4 video
  • Save the *.mp4 locally
  • Upload the *.mp4 to Azure Blob Storage
  • Play (progressive download) the *.mp4 from the Azure Storage location

The sequence has been perfectly implemented on iOS.

On Android however, I can record the video, save the video, upload the video, but cannot stream (progressive download) the file from Azure using VideoView and MediaController.

I get the "Can't play this video"

The video I uploaded from the Android app does work on iOS and HTML5 and pretty much any other media player.

If I choose to play the *.mp4 I saved locally (before uploading the *.mp4) through VideoView, it works fine. So at this stage, before uploading to Azure, the video seems in a working condition.

Another test I did, was to upload Big Buck Bunny, through Azure Storage Explorer, and that seems to work perfectly.

So I suspect I am might be missing a header when I upload the file to Azure or incorrect encoding for streaming.

Here is my code, nothing extraordinary:

MediaRecorder Settings to display and record the video:

mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setOutputFile(getVideoFile(activity).getAbsolutePath());
mediaRecorder.setVideoEncodingBitRate(1000000);
mediaRecorder.setVideoFrameRate(5);
mediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight());
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

Upload the file by using CloudBlockBlob:

StorageCredentials credentials = new StorageCredentialsSharedAccessSignature(sasQueryString);
URI containerUri = new URI(blobUri);
CloudBlockBlob blob = new CloudBlockBlob(URI.create(blobUri), credentials);
blob.getProperties().setContentType("video/mp4");
blob.uploadFromFile(imageUri);

Trying to play the uploaded file:

videoView = (VideoView) findViewById(R.id.videoView);
MediaController mediaController = new MediaController(this);
videoView.setVideoURI(Uri.parse("http://xox.blob.core.windows.net/container/movie.mp4"));
videoView.setMediaController(mediaController);
videoView.start();

At which point I get "Can't play this video"!

As I said to start off with, this uploaded file works seemingly on every other media player including iOS and HTML5. And if I play the locally saved version of the file on Android, it works.

But I can't play the file on Android from Azure after uploaded. Nor can I play the file created and uploaded by iOS created on Android.

Is it encoding the issue? Am I uploading the blob incorrectly? What makes Android's ViewVideo stricter on which video's it will play as oppose to other media players

3

3 Answers

1
votes

You probably calling the start() to early, start the video when the mediaplayer is ready to start playing: Reference MediaPlayer

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  public void onPrepared(MediaPlayer mp) {
    videoView.start();
  }
});
1
votes

Try using this Library: https://github.com/brianwernick/ExoMedia

It encapsulate ExoPlayer api similar to VideoView's API.

Also, facing issue while trying to play recorder and converted with FFMPEG videos from Azure Blob Storage.

0
votes

@Peter's answer should work. just instead of MediaPlayer.prepare() call MediaPlayer.prepareAsync() after setting Prepared listener.

And while recording in ios if you are simply changing extension of video from .mov to .mp4 then most of android device will not play it. also verify that in a MP4 container video stream should be encoded using H264 codec and audio with AAC codec.