How to serve mp4 streaming video on Google App Engine Blobstore - java

I am using GAE to serve large files, and I can successfully serve mp3 using a simple blobstoreService.serve(key, res); If I put the resource url in the browser, the media control will appear and/or the media player will start, and the music will start before the download is complete.
However, when I put a mp4 url in the Chrome, the control appears but nothing happens. Here are what I have done:
no content disposition to avoid download. If I put the content disposition, then the browser will download the video.
I even used ffmpeg to convert the video and put -movflags faststart option there but no difference.
I also set the response header to Accept-Ranges:bytes to the first request and I have observed that the next request still asks for full 75MB range. Should I only serve partially even though the browser asks for all?
Or how to let the browser know that I wanted to serve piece by piece so the requests will have ranges. Is content-length necessary? Should I process the HEAD request? I believe right now my servlet only processes GET.
my url is like http://www.somesite.com/serve?folder=aa&file=ok.MP4 the Chrome console shows that only 1MB is downloaded and then it stopped
The html code looks like below except my GAE url is the src. The example mp4 works but if my gae link is there, it doesn't show video at all.
<video width="640" controls="">
<source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
Question
What exactly are needed to do on GAE server side to serve the video using streaming?
Answer
The marked answer has sufficient information on how to serve the mp4 file and it also gives a live web page for demo. From that demo, I was able to tell that my site could serve an mp4 file as long as the Chrome browser could decode it. The problem I encountered was due to the codec used in ffmpeg wasn't recognized by Chrome. Changed to H.264, everything worked fine.
Here is one example of the ffmpeg command line, where OK.MTS is the camcorder file, output1.mp4 is to be uploaded:
ffmpeg -i ok.MTS -codec:v libx264 -profile:v baseline -preset slow -b:v 500k -maxrate 800k -bufsize 1000k -vf scale=-1:432 -threads 0 -b:a 96k output1.mp4

Is your handler putting the correct Content-Type in the response headers? You need to be setting "Content-Type:video/mp4" for the video to play correctly.
Here is a test site I wrote on App Engine that plays mp3, ogg and mp4 files from Cloud Storage and the BlobStore.
Here is a link to an mp4 file in the BlobStore that uses serve() to return the file. When I paste this link into chrome the content plays correctly.

Related

Kurento generated MP4 files not playing on Safari browsers

I have generated MP4 files of a live streaming done using Kurento Media Server 6.10. The saved file does play in the chrome and other browsers but do not play in Safari browsers.
The video to be played is being sent as a stream with response code as 206 (as required by safari browser
I have tried autoplay tag in . Have looked into the encoding of the video and it is a proper mp4 file.
I was not able to alter/code the moov atom metadata to the start of the video as stated here https://doc-kurento.readthedocs.io/en/6.10.0/knowledge/mp4.html#mp4-fast-start-in-kurento
Below is the code snippet which records my video.
RecorderEndpoint recorderEndpointA = new RecorderEndpoint.Builder(pipeline,"file:///tmp/recording.mp4").withMediaProfile(MediaProfileSpecType.MP4).build();
masterWebRtc.connect(recorderEndpointA);
//masterWebRtc is source, recorderEndpointA is sink
recorderEndpointA.record();
Modified from this code repo https://github.com/Kurento/kurento-tutorial-java/tree/master/kurento-one2one-call-recording
The video thus generated should be played as a streamed video over the internet on the page rendered in safari browsers.
I have uploaded one of such sample over here
https://drive.google.com/open?id=1YMnOMaJ1EQDHWezxkMY-JYHzKxmwO8H2

Doing an http file upload to a Google App Engine is really damn slow

I have this experimental endpoint on my Google App Engine Java servlet app, and it accepts multipart HTTP form posts. I noticed that when I do an HTTP multi-part form post with a file that is like 20 MB.
When I experiment by doing the HTTP post file upload from CURL, I see that curl finishes uploading the file to 100% in about 10 seconds, but then there is almost like 12 - 15 seconds of the Google App Engine doing some processing ( I guess it is reading the file that was stored in a temporary location?? ) before it actually starts running the code of that app engine endpoint.
Can anyone clarify if it is normal for App Engine to take that long to process uploaded files?
Thanks

LibVLC Android stream from minimal HTTP server

I am trying to write an application similar to the well-known Popcorn Time - an app which lets you watch movies over torrents. It basically uses NanoHTTPD as a bridge between the LibVLC player and the torrent library to be able to stream it. I use this exact same HTTP library.
The problem I have is that, even though using chrome's built-in MP4 viewer works fine, I cannot play the video from VLC. I did notice that it sends an 'Icy-Metadata: 1' header in the HTTP request which Chrome doesn't but little is documentated on that so I'm not sure if that's the problem here.
The desktop version of VLC player does not play it either. It stands there, requesting the same over and over again without displaying my video. What could I be missing?
It may be worth noting that nginx serves it properly, but it seems like nginx doesn't even reply with any kind of http header response. Just data.

How to upload a larger file from a java mobile app?

I have done a backup and restore application for java phone including nokia, it works fine but pictures larger than 1 MB cannot be uploaded is that possible to upload a file larger than 1 MB, if so please suggest me whether it is possible on HTTP or FTP.
Thank you.
Have a look at this step by step tutorial. What you need is to send files in multiple parts over a persistent HTTP connection.
Uploading files to HTTP server using POST on Android.

Http Header Range (HTML + Java Example)

I have a requirement to load big images into chrome browser, in pieces from the server and after it finishes downloading the file completely, if the user wants to look at the file again, then the browser should load it from its cache.
I have done the following to achieve this:
I have written a HTML file and I will be displaying the big image using 'img' tag.
Whenever the user requests for the image file, I'll make a HEAD request to the server enquiring about the content-length and last-modified-date.
The server replies back with the information based on the request and I divide the size of the file into 10 pieces and then make 10 sequential requests to fetch the image file. (Using for loop).
After chrome downloads the entire file and the next time user wants to look at the file, then I am making chrome to send If-Modified-Since query to the server.
If the server responds back with the code 304, then chrome will understand that it has to fetch the file from its cache.
I am facing the following problems:
1. I am getting about 100 bytes per response. Where should I store it and how should I make my img tag understand that it the client is still downloading the file.3
2. How should I recognize the file from the pool of files present in chrome's cache ?
3. The next time someone comes to view the same image, from where should I display the content from ?
Please Help. Can anyone also provide me with some example code or a link to some sample code.
Thanks and Regards,
Akshay Sahu
I got the way to perform this operation.
I am downloading all the bytes of a file in range and using File API of HTML 5 I am creating a file in the user HDD. Therefore, experiencing a complete resume download experience.
Thanks and Regards,
Akshay Sahu.

Categories