2

I achieved to get a video from php using this code :

var some_video_element = document.querySelector('video')
var req = new XMLHttpRequest();
req.onload = function () {
    var blob_uri = URL.createObjectURL(this.response);
    some_video_element.src = blob_uri;
    some_video_element.addEventListener('oncanplaythrough', (e) => {
       URL.revokeObjectURL(blob_uri);
    });
};
req.open("get", "vid.php", true);
req.overrideMimeType('blob');
req.send(null);

However, the loading is long so I want to show data as soon as I get it. From Mozilia, it is indicated we can use plain or "" as mime to get the text in progress. However, I can't achieve to convert plain/text to video/mp4 using a blob. Currently this is the code that doesn't work. I try to get the video when some part is available while the rest is still downloading.

var some_video_element = document.querySelector('video')
var req = new XMLHttpRequest();
req.onprogress = function () {
    var text = b64toBlob(Base64.encode(this.response), "video/mp4");
    var blob_uri = URL.createObjectURL(text);
    some_video_element.src = blob_uri;
    some_video_element.addEventListener('oncanplaythrough', (e) => {
       URL.revokeObjectURL(blob_uri);
    });
};
req.onload = function () {
    var text = b64toBlob(this.response, "video/mp4");
    var blob_uri = URL.createObjectURL(text);
    some_video_element.src = blob_uri;
    some_video_element.addEventListener('oncanplaythrough', (e) => {
       URL.revokeObjectURL(blob_uri);
    });
};
req.open("get", "vid.php", true);
req.overrideMimeType('text\/plain');
req.send(null);

Thanks. NB : This JavaScript is fetching for this php code : https://codesamplez.com/programming/php-html5-video-streaming-tutorial But echo data has been changed by echo base64_encode(data);

JoelCrypto
  • 462
  • 2
  • 12
  • Hello @JoelCrypto please share PHP code – Lucas Roquilly Jun 04 '22 at 22:56
  • I have changed my post. – JoelCrypto Jun 05 '22 at 06:16
  • I think your question is missing a lot of information. It seems like you are trying to stream a video from a php backend, but it doesn't look like you JS code reflects that. You might have to look into https://developer.mozilla.org/en-US/docs/Web/API/Streams_API Then again, HTML5 video tag should be able to handle a video url out of the box, even if the video gets streamed from the backend. You should first try just putting inside video tags and see how that works out for you. – Swiffy Jun 07 '22 at 10:35
  • Yes but using this some one could easily download my vidéo and i don’t want this. I know it could be possible but I dont want this to be do easy. Moreover vidéos are outside webroot. I will take a look at stream api. – JoelCrypto Jun 07 '22 at 11:11
  • I will take a look at stream api. Actually i want to stream a video that cannot be downloaded easily (blocked beyond js or html) and can be play as soon as data is on. I have tried Canvas but quality is not that good… – JoelCrypto Jun 07 '22 at 11:18
  • Have a look here also https://medium.com/canal-tech/how-video-streaming-works-on-the-web-an-introduction-7919739f7e1 – Swiffy Jun 07 '22 at 22:42

2 Answers2

1

As indicated in the comments, you are missing some decent components.

You can implement what you are asking for but you need to make some changes. Following up on the HTML5 streaming API you can create a stream that will make the video using segments you fetch from the server.

Something to keep in mind is the HLS or DASH protocol that already exists can help, looking at the HLS protocol can help as it's simple to use with the idea of segments that can reach out to your server and just decode your base64'd feed.

https://videojs.github.io/videojs-contrib-hls/

Noah
  • 859
  • 7
  • 17
1

If you use the Fetch API instead of XMLHttpRequest you can consume the response as a ReadableStream which can be fed into a SourceBuffer. This will allow the video to be playable as soon as it starts to load instead of waiting for the full file to download. This does not require any special video container formats, back-end processing or third-party libraries.

const vid = document.getElementById('vid');
const format = 'video/webm; codecs="vp8,vorbis"';
const mediaSource = new MediaSource();
let sourceBuffer = null;

mediaSource.addEventListener('sourceopen', event => {
  sourceBuffer = mediaSource.addSourceBuffer(format);
  fetch('https://bes.works/dev/samples/test.webm')
  .then(response => process(response.body.getReader()))
  .catch(err => console.error(err));
}); vid.src = URL.createObjectURL(mediaSource);

function process(stream) {
  return new Response(
    new ReadableStream({
      start(controller) {
        async function read() {
          let { done, value } = await stream.read();
          if (done) { controller.close(); return; }
          sourceBuffer.appendBuffer(value);
          sourceBuffer.addEventListener(
            'updateend', event => read(),
            { once: true }
          );
        } read();
      }
    })
  );
}
video { width: 300px; }
<video id="vid" controls></video>
Besworks
  • 4,123
  • 1
  • 18
  • 34
  • That seems great. I have the duration of the video but no video :/ – JoelCrypto Jun 09 '22 at 17:37
  • Did you change the `format` to match your source file? Are there any errors in the console log? – Besworks Jun 09 '22 at 17:49
  • Yes i changed to video/mp4. No error as soon as i have changed the format. There is the blob in the src and the duration of video but Then only loading image. – JoelCrypto Jun 09 '22 at 18:18
  • Apparently this method [cannot be used](https://stackoverflow.com/a/24152971/6036546) for **h264** encoded video, which is likely what you are using in your **mp4** container. The easiest way to get this working would be to [convert](https://stackoverflow.com/q/28029411/6036546) your source files to [webm](https://en.wikipedia.org/wiki/WebM). This is something you should be doing anyway as this format was designed specifically for use on the web and creates significantly smaller files than other formats which is nicer to your users with bandwidth caps. – Besworks Jun 09 '22 at 19:02
  • I did not achieve to convert to webm via VLC but i will manage myself. It is working well, except on iOS because mediasource is not supported but that would be fine. Many thanks! – JoelCrypto Jun 09 '22 at 19:35
  • Happy to help. Good luck with the rest of your project. – Besworks Jun 09 '22 at 19:36