Stream part of the video to the client - javascript

Given a windows server backend, is there a way to implement a pure javascript/html5 client that would be able to play only a designated part of the video file (e.g. from 10th second to 15th on a 2 hour video)?
From what I know, standard html5 video tag will download an entire file which is not suitable for my situation.
Streaming solutions on the server would probably be an answer, but are there any that would work with pure javascript/html client? Thanks.

To do this you should encode your video into one of the segmented/fragmented format like MPEG-DASH or Apple HLS. The result will be a playlist file and 1 or more media files containing 2 to 10 second fragments of your (long) video file. For DASH you will normally have 1 fragmented MP4 file containing 2 second fragments of video, the playlist file will tell your player which parts of the file to download corresponding to the time you wish to play. For this to work your web server needs to support HTTP RANGE headers (which most do).
For HLS you will normally end up with multiple 10 second files. The playlist file will tell the player which file to download for the time to play.
Here's how to build a HTML5 player to play DASH streams:
http://blogs.msdn.com/b/interoperability/archive/2014/01/03/mpeg-dash-tutorial-embedding-an-adaptive-streaming-video-within-your-html5-application.aspx
http://www-itec.uni-klu.ac.at/dash/?page_id=746

Besides complex methods like HLS or MPEG-DASH you can consider using pseudo-streaming, or progressive download. Its seeking capability supported by a number of media servers will allow you to watch the MP4 video from any moment. Using Javascript you should be able to actually setup play and stop when you need (but that's up you to deal with different browsers handling playback in HTML5 video container).

Related

How to cache audio file delivered from CloudFront using JavaScript / jQuery?

We are developing an online course website.
Courses have audio and text (no video).
Audio files are stored on Amazon S3 and delivered via AWS CloudFront.
Every time a user wants to play a course audio file,
website (server-side) sends a request to CloudFront to get the audio file.
CloudFront will deliver the audio file to the end-user (HTTTP response).
We use JPlayer to play the audio files.
Audio file format is MP3
We are facing the following issue:
Every time a user clicks on play/pause, forward, rewind buttons OR
jumps to a specific position on the audio player,
a new request (for the same audio file) is being sent to CloudFront,
so audio player position is reset to 00:00
Since CloudFront already delivered the audio file to end-user,
there is no need to generate a new request to CloudFront
every time user clicks on audio player buttons (play/pause, forward, rewind) etc.
So once user gets the audio file from CloudFront,
we want to cache the audio file.
How can we store an audio file in local browser cache using JavaScript or jQuery?
Caching audio files should be done using browser caching.
There are several ways to implement "browser caching".
Huge thanks for "stdunbar" for sharing the following link.
This link points to a great article that provides
an overview of the different browser caching solutions.
https://web.dev/storage-for-the-web/
For my use-case, the optimal solution for audio file caching is IndexedDB.
Here are some great articles on how to get-started with IndexedDB (IDB):
Basic concepts
https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB
Path locations in different browsers
IndexedDB location in Windows 8 Application
Tutorial 1
https://www.tutorialspoint.com/html5/html5_indexeddb.htm
Tutorial 2
https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
Tutorial 3
http://www.onlywebpro.com/2012/12/23/html5-storage-indexeddb/

generate headers for webm file to play downloaded corrupted media

there is a website that fetches some .webm files from their server, some are what appears to be chunks of the file, the more it plays, others appear to be some form of the complete webm file.
However, when attempting to play any of these files in a custom video element or any other vide player, it is either just black, or white, or doesn't play.
I think it has to do with incomplete headers
I suspect that the host website downloads some kind of chunk of the video from the server, then somehow appends the webm headers separately in order play it in their own player
The thing is, I want to be able to play (and eventually download) a fully operational .webm file, based on the other corrupted webm files, and I suspect the way to do this is to write some custom .webm headers and append them to the beginning of the video, and this is where I need some help.
I'm aware there is the WebM Specification, I just don't know how to use it with client-side JavaScript to accomplish what I need here, or if this is even the right kind of solution, because I've also heard of the MediaSource API, which I also suspect is used for this (website is here)
You do not need to obtain each part of the webm files. Just adjust the interval parameter, at the end of the request, and download the complete file.
For example:
https://r1---sn-b8u-nn5l.googlevideo.com/videoplayback?...&range=0-76746&...
...&range=76746-183717&...
...&range=398277-751324&...
...&range=751325-1387287&...
You just need change the start and final range to get the part you wish
...&range=0-1387287&...

nodejs ffmpeg play video at specific time and stream it to client

I'm trying to make a basic online video editor with nodeJS and ffmpeg.
To do this I need 2 steps:
set the in-and-out times of the videos from the client, which requires the client to view the video at specific times, and switch the position of the video. Meaning, if a single video is used as an input, and split it into smaller parts, it needs to replay from the starting time of the next edited segment, if that makes sense.
send the input-output data to nodejs and export it with ffmpeg as a finished vide.
At first I wanted to do 1. purely on the client, then upload the source video(s) to nodeJS, and generate the same result with ffmpeg, and send back the result.
But there are may problems with video processing on the client side in HTML at the moment, so now I have a change of plans: to do all of the processing on the nodeJS server, including the video playing.
This is the part I am stuck at now. I'm aware that ffmpeg can be used in many different ways from nodeJS, but I have not found a way to play a .mp4 webm video in realtime with ffmpeg, at a specific timestamp, and send the streaming video (again, at a certain timestamp) to the client.
I've seen the pipe:1 attribute from ffmpeg, but I couldn't find any tutorials to get it working with an mp4 webm video, and to parse the stdout data somehow with nodejs and send it to the client. And even if I could get that part to work, I still have no idea to play the video, in realtime, at a certain timestamp.
I've also seen ffplay, but that's only for testing as far as I know; I haven't seen any way of getting the video data from it in realtime with nodejs.
So:
how can I play a video, in nodeJS, at a specific time (preferably with ffmpeg), and send it back to the client in realtime?
What I have already seen:
Best approach to real time http streaming to HTML5 video client
Live streaming using FFMPEG to web audio api
Ffmpeg - How to force MJPEG output of whole frames?
ffmpeg: Render webm from stdin using NodeJS
No data written to stdin or stderr from ffmpeg
node.js live streaming ffmpeg stdout to res
Realtime video conversion using nodejs and ffmpeg
Pipe output of ffmpeg using nodejs stdout
can't re-stream using FFMPEG to MP4 HTML5 video
FFmpeg live streaming webm video to multiple http clients over Nodejs
http://www.mobiuso.com/blog/2018/04/18/video-processing-with-node-ffmpeg-and-gearman/
stream mp4 video with node fluent-ffmpeg
How to get specific start & end time in ffmpeg by Node JS?
Live streaming: node-media-server + Dash.js configured for real-time low latency
Low Latency (50ms) Video Streaming with NODE.JS and html5
Server node.js for livestreaming
HLS Streaming using node JS
Stream part of the video to the client
Video streaming with HTML 5 via node.js
Streaming a video file to an html5 video player with Node.js so that the video controls continue to work?
How to (pseudo) stream H.264 video - in a cross browser and html5 way?
Pseudo Streaming an MP4 file
How to stream video data to a video element?
How do I convert an h.264 stream to MP4 using ffmpeg and pipe the result to the client?
https://medium.com/#brianshaler/on-the-fly-video-rendering-with-node-js-and-ffmpeg-165590314f2
node.js live streaming ffmpeg stdout to res
Can Node.js edit video files?
This question is a bit broad, but I've built similar things and will try to answer this in pieces for you:
set the in-and-out times of the videos from the client, which requires the client to view the video at specific times, and switch the position of the video. Meaning, if a single video is used as an input, and split it into smaller parts, it needs to replay from the starting time of the next edited segment, if that makes sense.
Client-side, when you play back, you can simply use multiple HTMLVideoElement instances that reference the same URL.
For the timing, you can manage this yourself using the .currentTime property. However, you'll find that your JavaScript timing isn't going to be perfect. If you know your start/end points at the time of instantiation, you can use Media Fragment URIs:
video.src = 'https://example.com/video.webm#t=5.5,30';
In this example, the video starts at 5.5 seconds, and stops at 30 seconds. You can use the ended event to know when to start playing the next clip. This isn't guaranteed to be perfectly frame-accurate, but is pretty good for something like a live preview.
But there are may problems with video processing on the client side in HTML at the moment, so now I have a change of plans: to do all of the processing on the nodeJS server,...
Not a bad plan, if consistency is important.
... including the video playing.
There is a serious tradeoff you're making here, as far as latency to controlling that video, and quality of preview. I'd suggest a hybrid approach where editing is done client-side, but your final bounce/compositing/whatever is done server-side.
This isn't unlike how desktop video editing software works anyway.
This is the part I am stuck at now. I'm aware that ffmpeg can be used in many different ways from nodeJS, but I have not found a way to play a .mp4 webm video in realtime with ffmpeg, at a specific timestamp, and send the streaming video (again, at a certain timestamp) to the client.
Is it MP4, or is it WebM? Those are two distinct container formats. WebM is easily streamable, as piped directly out of FFmpeg. MP4 requires futzing with the MOOV atom (-movflags faststart), and can be a bit of a hassle.
In any case, sounds like you just need to set timestamps on the input:
ffmpeg -ss 00:01:23 -i video.mp4 -to 00:04:56 -f webm -
I've seen the pipe:1 attribute from ffmpeg, but I couldn't find any tutorials to get it working with an mp4 webm video, and to parse the stdout data somehow with nodejs and send it to the client.
Just use a hyphen - as the output filename and FFmpeg will output to STDOUT. Then, there's nothing else you need to do in your Node.js application... pipe that output directly to the client. Untested, but you're looking for something like this, assuming a typical Express app:
app.get('/stream', (req, res, next) => {
const ffmpeg = child_process.spawn('ffmpeg', [
'-i', 'video.mp4',
'-f', 'webm',
'-'
]);
res.set('Content-Type', 'video/webm'); // TODO: Might want to set your codecs here also
ffmpeg.stdout.pipe(res);
});
And even if I could get that part to work, I still have no idea to play the video, in realtime, at a certain timestamp.
Well, for this, you're just playing a stream so you can just do:
<video src="https://your-nodejs-server.example.com/stream" preload="none" />
The preload="none" part is important, to keep it "live".
An alternative to all of this is to set up a GStreamer pipeline, and probably utilize its built-in WebRTC stack. This is not trivial, but has the advantage of potentially lower latency, and automatic handling of "catching up" to live video from the server. If you use the normal video tag, you'll have to handle that yourself by monitoring the buffered data and managing the playback speed.
I've also seen ffplay...
FFplay isn't relevant to your project.
Hopefully this pile of notes will give you some things to consider and look at.

mediasource local video segment by js

I want to play local video by web browser with js. Normally, it would be solved with html5 video tag. but the video was too big, ram couldn't contain it. So I decided to streaming local video file on browser not through server. I search it and I found that mediasource API able to do that, but I failed play my video. I search again more then I found video segments(initialization segments and media segments) form needed. but I couldn't find the way how to make it.
how can make video segments by js?
Is there any kind of api support to make it?
please not just about mp4box. mp4box is just for mp4 type. I want play every type of video that supported in video tag.

Dynamic streaming of a video on a website

I'd like to publish a video on my website. I use javascript and SWFObject to allow to watch it directly on the website. The format of the video is mp4 and it's quite a big file - let's say about 300MB. Thus, it takes a while until it loads in the player. I'd like the visitors to start watching the video while it's not fully downloaded. In other word, I'd like to stream in the way e.g. Youtube does.
The small example I uploaded there:
http://geoportaltoskania.t15.org/Film360.html
Here you can find all files and codes that are used for this:
http://geoportaltoskania.t15.org
Thanks, Krzychu
You can use the following options:
1) MPEG-Dash - https://msopentech.com/blog/2014/01/03/streaming_video_player/
2) VideoJS - https://github.com/videojs/video.js/blob/stable/docs/guides/setup.md
MPEG-DASH or HLS is a good solution for your problem. You can take your file and transcode it to HLS and MPEG-DASH using e.g. http://www.bitcodin.com, put it on your webserver and playback it with e.g. http://www.dash-player.com

Categories