Chrome desktop can play this .mp4 video, but Chrome mobile can not - stream

there is a .mp4 video in this url,
http://forum.tinnitus-light.org/topic_933_1.html
Chrome desktop can play this .mp4 video, but Chrome mobile can not and tips 'sorry, this video cannot play', I have no idea about this...
more info about this video is this file does not storage in server Physical, it is generated by ADODB.Stream reading and BinaryWrite, is something miss setting about http header or etc.?
here are code about binary read:
<%
Response.Buffer = true
Response.Clear
Response.ContentType = "video/mp4"
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1
objStream.LoadFromFile "file_real.mp4"
Response.AddHeader "Content-Disposition", "attachment; filename="download.mp4"
Response.AddHeader "Content-Length", 16815358
Response.Charset = "UTF-8"
Response.BinaryWrite objStream.Read
Response.Flush
objStream.Close
Set objStream = Nothing
%>
Thank you!

the problem was found.
the server using HTTP_REFERER to check if the request is acceptable. In android system, when chrome play the audio/video file in html5 page, it pass the request to 'mediaserver' in system but without HTTP_REFERER, so the server block this request.
thank you anyway.

Related

Browser caching of images served by Grails

I have a controller action which reads an image from the database and serves it to the client:
def profilePicture() {
def profilePicture = ProfilePicture.get(1)
response.setHeader("Content-disposition", "attachment; filename=1.png")
response.contentType = "PNG"
response.outputStream << profilePicture.profilePicture
response.outputStream.flush()
}
Every time the client requests the image, the server serves the whole image with status 200. What can I do to instruct the client that this content can be cached?
I have already tried response.setHeader("Expires", "...") with a date in the future but this didn't help (I'm guessing this is only part of the story as the server is not returning 304).
Actually, there is a plugin called Caching Headers for Grails which will handle all the needed caching and etag generation so that browsers won't request the download of the file when it's not modified and within your configured caching period.
It's pretty simple to use if you read through the documentation and take your time to test your configuration.

Is it possible to compose URL that forces browser to download file instead of play it?

Let say we have some file at http://somedomain.com/somedir/file.mp4.
When I send such URL to someone, I would like that browser start download, not play automatically.
Is it possible to compose URL in such manner to give browser instruction to start download instead of play it? With some parameter included maybe?
You can't do that by just sending the URL to someone.
What you can do is create a simple file which forces the user to download the file by setting the mime type of the response to octet/stream, which is the way of telling the browser the file can not embedded.
Below is an example in PHP taken from this website.
<?php
$file = $_GET['file'];
header ("Content-type: octet/stream");
header ("Content-disposition: attachment; filename=".$file.";");
header("Content-Length: ".filesize($file));
readfile($file);
exit;
?>

Grails Base64 to PDF - render a PDF inline

I have a Grails controller action that calls a service that will return XML that contains a base64 representation of a PDF. Here is an (abbreviated) example sample.
<response status="Success"><messages/><values><pages>8</pages></values><xml/><files><pdf name="FitnessApplication" content-type="application/pdf"><![CDATA[JVBERi0xLjQKJeL ... </files></response>
After we parse that out I want to display that PDF in the browser. So far I am able to decode the string and render it using the file attribute of the render method. This serves up the PDF correctly as a download but I want it to display in the browser (inline) and NOT as a file download.
Map responseMap = new XmlParserHelper().parse( formsResponse.payload )
byte[] decoded = responseMap.files.pdf.decodeBase64()
render( file: decoded, fileName: "${document}.pdf", contentType: "application/pdf", )
I tried setting the content disposition as both an option to render and in the header map but neither seem to do the trick. Does anyone know how I can serve this PDF to the user in the browser?
Just send it in the response. But you need to add the headers on your own. E.g. something like:
response.contentType = "application/pdf"
response.contentLength = FileUtils.copyFile(pdfFile, response.outputStream)
To build on what cfrick said here is the final solution I went with.
// response data
byte[] pdfData = responseMap.files.pdf.decodeBase64()
response.contentType = "application/pdf"
response.setHeader("Content-disposition", "inline; filename='dan.pdf'")
// write to output
OutputStream output = response.outputStream
output.write(pdfData);
output.close();

Rails and HTML5 Video MimeTypes Unsupported

I am working on a simple Rails app where I would like to play a video that is uploaded to the application. The video I am uploading is a h264/MP4 video, I have verified the codec. It's uploaded fine and I can watch the video in the browser if I go to the URL.
However, when trying to use HTML5 to display the video, on the page I get
Video format or MIME type is not supported
In my config/initializers/mime_types.rb file I have tried the following...
Mime::Type.register "video/mp4", :mp4
MIME::Types.add(MIME::Type.from_array("video/mp4", %(mp4)))
Taken from this question: Rails: MIME type issues with .m4v files
And I have also tried...
Rack::Mime::MIME_TYPES.merge!({
".ogg" => "application/ogg",
".ogx" => "application/ogg",
".ogv" => "video/ogg",
".oga" => "audio/ogg",
".mp4" => "video/mp4",
".m4v" => "video/mp4",
".mp3" => "audio/mpeg",
".m4a" => "audio/mpeg"
})
I remembered to restart my server after trying those different MIME initializers.
But neither seems to work. Any ideas?
EDIT: Also I should note when I run
curl -I http://localhost:3000/videos/SAMPLE.mp4 | grep Content-Type
I get back "Content-Type: video/mp4".
EDIT 2: Answer posted below.
Turns out everything I posted code-wise is fine. It was just a browser compatibility issue (MP4 on Firefox)...well, hopefully someone will find my misfortune useful!

Ruby-Rails serve ftp file direct to client

I am new to ruby and to rails, so excuse my question... .
What i want to know is, how to take a file from a ftp server with ruby without saving the file on my rails application harddrive (streaming the filedata direct to the client). I am working with the ruby Net/FTP class.
With the method "retrbinary" from the Net/FTP class i have the following snippet:
ftp.retrbinary('RETR ' + filename, 4096) { |data|
buf << data
}
In my rails view i can do something like this:
send_data( buf )
So how do i combine these two. I dont know how to instanziate a buffer object, fill in the stream and than serve it to the user. Has anybody an idea how to do this?
thank you very much for your support! Your post get me going on. After some cups of coffee i found a working solution. Actually i am doing the following, which works for me:
def download_file
filename = params[:file]
raw = StringIO.new('')
#ftp.retrbinary('RETR ' + filename, 4096) { |data|
raw << data
}
#ftp.close
raw.rewind
send_data raw.read, :filename => filename
end
I will test this in production(real life situation). If this is not working well enough, i have to use a NFS mount.
fin
Do you want the following?
1) Client (browser) sends a request to the Rails server
2) Server should respond with the contents of a file that is located on an ftp server.
Is that it?
If so, then simply redirect the browser to the ftp location. Eg
# in controller
ftp_url = "ftp://someserver.com/dir_name/file_name.txt
redirect_to ftp_url
The above works if the ftp file has anonymous get access.
If you really need to access the file from the server and stream it, try the following:
# in controller
render :text => proc {|response, output|
ftp_session = FTP.open(host, user, passwd, acct)
ftp_session.gettextfile(remotefile) {|data| output.write(data)}
ftp_session.close
}
You should check the headers in the response to see if they're what you want.
ps. Setting up the ftp connection and streaming from a second server will probably be relatively slow. I'd use JS to show a busy graphic to the user.
I'd try alternatives to ftp. Can you set up an NFS connection or mount the remote disk? Would be much faster than ftp. Also investigate large TCP window sizes.

Resources