DOMException when sending audio file using Django - javascript

I am building a Django based web app in which I want to play an audio file from the server in the browser upon the click of a button. The file changes with the use of the app so I call a Django view through the src attribute of the audio element like so:
<audio id="audio" src="{% url 'play' 'for-sure' %}" type="audio/wav"></audio>
Here for-sure is the default filename to play. Here's the mapped view function:
def play(request, file_name):
with open(f'audio/{file_name}.wav', 'rb') as f:
response = HttpResponse(f.read(), status=206)
response['content_type'] = 'audio/wav'
return response
I also add a button to play the sound:
<input type="button" value="Play audio" onclick="play()" id="play_btn">
And the accompanying Javascript:
function play(){
var audioElement = document.getElementById("audio");
var promise = audioElement.play();
if (promise !== undefined) {
promise.then(_ => {
console.log('playing')
}).catch(error => {
console.log('playing error')
console.log(error)
console.log(error.message)
});
}
};
This works in Firefox (v68), but I keep getting DOMException: Failed to load because no supported source was found in Chromium (v76).
From what I've found it seems to be the AutoPlay prevention policy, but it should be also active in Firefox. If it is, I'm guessing it could be triggered by receiving the HTTP response by the view that wants to autoplay the audio.
I've also tried initing an AudioContext as here, and resuming it upon button click but to no avail.
What am I missing and how can I make it work?

Ok, so finally I've got it - it wasn't the AutoPlay Policy after all. Chrome doesn't support the audio element's src attribute to be the Django view's url (which responds with a HTTP Response audio file transfer). Hence Failed to load because no supported source was found.
As a solution, I switched to serving the audio files from my static directory setting the src to the static file's path. For example, the audio element init that points to the default sound now reads:
<audio id="audio" src="{% static 'annotate/audio/for-sure.wav' %}" type="audio/wav">
</audio>

Related

Display pdf file downloaded from database in an embed tag

We are trying to fetch pdf files from database in byte array format. when user clicks on display button it should be displayed in an embed tag which appears on top of screen. But when we convert the byte array to base64string it doesn't apear in embed file.
<td>
#Html.DisplayFor(modelItem => item.File)
Display
</td>
When user press Display button, OpenPDF script will open:
<script type="text/javascript">
function OpenPDF() {
document.getElementById("pdfBack").style.visibility = "visible";
document.getElementById("pdfDialog").style.visibility = "visible";
document.getElementById("pdfFile").setAttribute("src", "data:application/pdf;base64," + #Convert.ToBase64String(item.File));
}
</script>
And this is the embed tag:
<embed id="pdfFile" type="application/pdf" src="" width="100%" height="100%" />
It doesn't work! embed tag will open after pressing button, but there is no pdf file inside the mebed.
Please help us how should we handle this problem
To display a PDF properly directly on the browser you need to use some kind of PDF viewer ie google docs or you can use libraries like PDF.js.
Using google doc ->
<iframe src=" http://docs.google.com/gview?url=http://path.com/to/your/pdf.pdf&embedded=true" ></iframe>
For this to work you need to host your PDF's somewhere online.
You can also use PDF.js http://mozilla.github.io/pdf.js/examples/
check examples to make it work for you.
To make embed solution work you will need to host your file some where already and provide that path in your src.
<script type="text/javascript">
function OpenPDF() {
document.getElementById("pdfBack").style.visibility = "visible";
document.getElementById("pdfDialog").style.visibility = "visible";
document.getElementById("pdfFile").setAttribute("src", "http://yourwebsite.com/" + fileName );
}
</script>
<embed src="" width="500" height="375"
type="application/pdf">
I would suggest to use PDF.js if hosting the file is a problem.
Also chrome on android doesn't support embeds with PDF files so if you are expecting android users use PDF.js or google docs.

In video.js, how to solve the buffering problem by using playlist.m3u8 file format

I can't find my solution. I am going to play the playlist.m3u8 file with video tag of html5 in my website.
Below is my javascript code.
<html>
<body>
<video id="my-video" class="video-js" autoplay preload="auto" muted="false">
</video>
</body>
<link href="https://vjs.zencdn.net/7.4.1/video-js.css" rel="stylesheet">
<script src="https://vjs.zencdn.net/7.4.1/video.js"></script>
<script>
var myPlayer = videojs('my-video');
myPlayer.src('https://5bf6159570fba.streamlock.net/Bwin/Horses_0/playlist.m3u8');
myPlayer.play();
</script>
And at regular intervals i use the myPlayer.reset() function.
Contents of playlist.m3u8 file is below.
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=2566576,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=960x540
chunklist_w1328950476.m3u8
Contents of chunklist_w1328950476.m3u8 file is below.
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:2
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:2.0,
media_w1328950476_1.ts
#EXTINF:2.0,
media_w1328950476_2.ts
#EXTINF:2.0,
media_w1328950476_3.ts
If i run above code, the following error codes are dislayed at console.
video.js:142 VIDEOJS: ERROR: DOMException: Failed to set the 'duration' property on 'MediaSource':
The 'updating' attribute is true on one or more of this MediaSource's SourceBuffers.
at HtmlMediaSource.addSeekableRange_ (https://vjs.zencdn.net/7.4.1/video.js:49141:44)
at addSeekableRange (https://vjs.zencdn.net/7.4.1/video.js:55039:36)
at PlaylistLoader.<anonymous> (https://vjs.zencdn.net/7.4.1/video.js:55054:15)
at PlaylistLoader.data.dispatcher (https://vjs.zencdn.net/7.4.1/video.js:1818:33)
at trigger (https://vjs.zencdn.net/7.4.1/video.js:1954:27)
at PlaylistLoader.EventTarget.trigger (https://vjs.zencdn.net/7.4.1/video.js:2432:5)
at PlaylistLoader.haveMetadata (https://vjs.zencdn.net/7.4.1/video.js:39151:14)
at https://vjs.zencdn.net/7.4.1/video.js:39089:17
at Object.callback (https://vjs.zencdn.net/7.4.1/video.js:40086:9)
at cbOnce (https://vjs.zencdn.net/7.4.1/video.js:7220:17)
And Status of media_w1328950476_6.ts file is (cancelled).
I would appreciate it if you could find a solution to this problem as soon as possible.
Thanks for your time and attention

Setting source to a azure media player

I have a azure media player embedded in my SharePoint page.
The source to the file to be played is set dynamically through a script file.Th source files can be of wmv/mp4/mpg formats and retrived from a sharepoint video portal.
However the source is not being set or it throws some error.
Please find the code below.
HTML:
<video id="vid1" class="azuremediaplayer amp-default-skin video-responsive" autoplay controls width="100%" height="100%" poster="poster.jpg">
<p class="amp-no-js">
To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video
</p>
</video>
JS:
var myPlayer = amp('vid1', { /* Options */
"nativeControlsForTouch": false,
autoplay: false,
controls: true,
width: "640",
height: "400",
poster: ""
}, function() {
console.log('Good to go!');
// add an event listener
this.addEventListener('ended', function() {
console.log('Finished!');
});
}
);
myPlayer.src([{
"src": "<<URL to the source file in video portal>>",
"type": "type": "application/vnd.ms-sstr+xml"
}]);
The mime type you're using in your given code implies that you're trying to set a smoothstreaming source (application/vnd.ms-sstr+xml)
if you are setting the source as an MP4 you should use the mime type video/mp4
myPlayer.src([{ src: "YOUR_SOURCE.mp4", type: "video/mp4" }]);
you can check out this sample which plays back progressive MP4 content from the Azure Media Player samples page
Also, I'm not sure if this was a typo or not but you have "type": included in your code twice.
Please refer to https://amp.azure.net/libs/amp/latest/docs/.
Authentication token of a sharepoint videoportal file can be retreived using GetStreamingKeyAccessToken rest service.

PDF Reader not installed on browser - Wish to Auto download

<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="gistfile1.js"></script>
</head>
<body>
<p id="divPDF">Can't see the PDF?</p>
</body>
<script type="text/javascript">
var info = getAcrobatInfo();
if (info.acrobat == false){
window.location = "empty.pdf";
} else {
document.getElementById("divPDF").innerHTML = "<object data='empty.pdf' type='application/pdf' width='100%' height='100%'><p class='helpContent'>Can't see the PDF? Try <a href='empty.pdf' download='empty.pdf'>downloading the file</a>. If you're still having trouble, <a href='/contactUs.jsp'>contact us</a> or email us directly at <a href='mailto:support#guitarinstructor.com'>support#guitarinstructor.com</a>.</p></object>";
}
</script>
</html>
Here's what I'm looking at doing. IF the getAcrobatInfo TRUE, display the PDF.
If the getAcrobat returns FALSE, then automatically download the PDF.
I thought this would work on a window.location = "URL OF THE PDF", my browser still attempts to display it.
Is there any javascript or jQuery that I can implement that will allow me to force an auto download if the user's browser doesn't have a PDF Reader plugin?
Typically you must set the Content-disposition header to attachment to encourage a browser to download a file instead of displaying it. If you can do this, and your client side plugin detection works, you could edit your server side code to have a different URL depending on the disposition you want to send, and have that in your object src attribute or location.replace argument.
Additionally, in HTML5 there is a download attribute for the <a> tag, with an optional filename as the attribute value. Support for this is not in every browser.
Download
Note that a very common practice is to have a single link with a small blurb informing a user how to download a file (e.g. using the right mouse button).

How to start automatic download of a file in Internet Explorer?

How do I initialize an automatic download of a file in Internet Explorer?
For example, in the download page, I want the download link to appear and a message: "If you download doesn't start automatically .... etc". The download should begin shortly after the page loads.
In Firefox this is easy, you just need to include a meta tag in the header, <meta http-equiv="Refresh" content="n;url"> where n is the number of seconds and url is the download URL. This does not work in Internet Explorer. How do I make this work in Internet Explorer browsers?
SourceForge uses an <iframe> element with the src="" attribute pointing to the file to download.
<iframe width="1" height="1" frameborder="0" src="[File location]"></iframe>
(Side effect: no redirect, no JavaScript, original URL remains unchanged.)
I hate when sites complicate download so much and use hacks instead of a good old link.
Dead simple version:
Start automatic download!
It works! In every browser!
If you want to download a file that is usually displayed inline (such as an image) then HTML5 has a download attribute that forces download of the file. It also allows you to override filename (although there is a better way to do it):
Download
Version with a "thanks" page:
If you want to display "thanks" after download, then use:
<a href="file.zip"
onclick="if (event.button==0)
setTimeout(function(){document.body.innerHTML='thanks!'},500)">
Start automatic download!
</a>
Function in that setTimeout might be more advanced and e.g. download full page via AJAX (but don't navigate away from the page — don't touch window.location or activate other links).
The point is that link to download is real, can be copied, dragged, intercepted by download accelerators, gets :visited color, doesn't re-download if page is left open after browser restart, etc.
That's what I use for ImageOptim
I recently solved it by placing the following script on the page.
setTimeout(function () { window.location = 'my download url'; }, 5000)
I agree that a meta-refresh would be nicer but if it doesn't work what do you do...
I had a similar issue and none of the above solutions worked for me. Here's my try (requires jquery):
$(function() {
$('a[data-auto-download]').each(function(){
var $this = $(this);
setTimeout(function() {
window.location = $this.attr('href');
}, 2000);
});
});
Usage: Just add an attribute called data-auto-download to the link pointing to the download in question:
<p>The download should start shortly. If it doesn't, click
<a data-auto-download href="/your/file/url">here</a>.</p>
It should work in all cases.
A simple bit of jQuery solved this problem for me.
$(function() {
$(window).bind('load', function() {
$("div.downloadProject").delay(1500).append('<iframe width="0" height="0" frameborder="0" src="[YOUR FILE SRC]"></iframe>');
});
});
In my HTML, I simply have
<div class="downloadProject"></div>
All this does is wait a second and a half, then append the div with the iframe referring to the file that you want to download. When the iframe is updated onto the page, your browser downloads the file. Simple as that. :D
I used this, seems working and is just simple JS, no framework:
Your file should start downloading in a few seconds.
If downloading doesn't start automatically
<a id="downloadLink" href="[link to your file]">click here to get your file</a>.
<script>
var downloadTimeout = setTimeout(function () {
window.location = document.getElementById('downloadLink').href;
}, 2000);
</script>
NOTE: this starts the timeout in the moment the page is loaded.
Works on Chrome, firefox and IE8 and above:
var link = document.createElement('a');
document.body.appendChild(link);
link.href = url;
link.click();
This is what I'm using in some sites (requires jQuery).:
$(document).ready(function() {
var downloadUrl = "your_file_url";
setTimeout("window.location.assign('" + downloadUrl + "');", 1000);
});
The file is downloaded automatically after 1 second.
I checked and found, it will work on button click via writing onclick event to Anchor tag or Input button
onclick='javascript:setTimeout(window.location=[File location], 1000);'
Back to the roots, i use this:
<meta http-equiv="refresh" content="0; url=YOURFILEURL"/>
Maybe not WC3 conform but works perfect on all browsers, no HTML5/JQUERY/Javascript.
Greetings Tom :)
One more :
var a = document.createElement('a');
a.setAttribute('href', dataUri);
a.setAttribute('download', filename);
var aj = $(a);
aj.appendTo('body');
aj[0].click();
aj.remove();
I hope this will works all the browsers. You can also set the auto download timing.
<html>
<head>
<title>Start Auto Download file</title>
<script src="http://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(function() {
$('a[data-auto-download]').each(function(){
var $this = $(this);
setTimeout(function() {
window.location = $this.attr('href');
}, 2000);
});
});
</script>
</head>
<body>
<div class="wrapper">
<p>The download should start shortly. If it doesn't, click
<a data-auto-download href="auto-download.zip">here</a>.</p>
</div>
</body>
</html>
Be sure to serve up the file without a no-cache header! IE has issues with this, if user tries to "open" the download without saving first.
This seemed to work for me - across all browsers.
<script type="text/javascript">
window.onload = function(){
document.location = 'somefile.zip';
}
</script>
For those trying to trigger the download using a dynamic link it's tricky to get it working consistently across browsers.
I had trouble in IE10+ downloading a PDF and used #dandavis' download function (https://github.com/rndme/download).
IE10+ needs msSaveBlob.
I think this will work for you. But visitors are easy if they got something in seconds without spending more time and hence they will also again visit your site.
<a href="file.zip"
onclick="if (event.button==0)
setTimeout(function(){document.body.innerHTML='thanks!'},500)">
Start automatic download!
</a>
Nice jquery solution:
jQuery('a.auto-start').get(0).click();
You can even set different file name for download inside <a> tag:
Your download should start shortly. If not - you can use
direct link.
<meta http-equiv="Refresh" content="n;url">
That's It. Easy, Right?
<meta http-equiv="Refresh" content="n;url">
This is an old question but in case anyone wants to use automatic download of files with Flask, Python. You can do this:
from flask import Flask, make_response, send_from_directory
file_path = "Path containing the file" #e.g Uploads/images
#app.route("/download/<file_name>")
def download_file(file_name):
resp = make_response(send_from_directory(file_path, file_name)
resp.headers['Content-Disposition'] = f"attachment; filename={file_name}"
return resp
Inside a template or html page, index for example
<div>
<a class="btn btn-outline-warning" href={{url_for( 'download_file', name='image.png' )}} ">Download Image</a>
</div>
Clicking on the link will download the file without opening another page.
For more info on:
Content-Disposition
Setting request headers in Flask

Categories

Resources