Vl ad
Vl ad

Reputation: 31

How to display playable Video Url from Blob

I am trying to download videos from a webDav server to my server. After that the videos should be viewable as well as playable on my client. For downloading I use the webdav library from npm. The download of the videos works on my server, as well as the transmission of the data to my client. My Problem is, I can't play those videos on the generated website.

app.post("/someroute/api", async (req, res) => {
let result = [];

try {
    const { username, password, targetUrl, data } = req.body;
    const dataFull = `somedata_${data}`;
    const client = createClient(targetUrl, {
        username: username,
        password: password,
    });
    const filesToDownload = await client.getDirectoryContents(`/${dataFull}`);
    const downloadPromises = filesToDownload.map(async (file) => {
        const fileBuffer = await client.getFileContents(file.filename);
        result.push({name: file.basename, buffer: fileBuffer});
    });
    await Promise.all(downloadPromises);
} catch (error) {
    console.error(error);
    res.status(500).json({ error: "Error retrieving directory contents" });
}
console.log(result);
res.send(result);});

The result looks like this :

{ name: 'butterfly slow motion [oAI-OqTmJj4].mp4', buffer: <Buffer 00 00 00 18 66 74 79 70 6d 70 34 32 00 00 00 00 69 73 6f 6d 6d 70 34 32 00 00 40 d7 6d 6f 6f 76 00 00 00 6c 6d 76 68 64 00 00 00 00 d8 cd f6 85 d8 cd ... 4073099 more bytes> }

On the client side I have this function to request the videos and store them in a useState.

useEffect(() => {
        if (selectedData) {
            getDataVideos();
        }
    }, [selectedData]);
    

    const getDataVideos = async () => {
        try {
            const response = await fetch("/someroute/api", {
                method: "POST",
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify({
                    username: username,
                    password: password,
                    targetUrl: targetUrl,
                    data: selectedData,
                }),
            });
            const content = await response.json();
            console.log(content);
            setSelectedDataVideos(content);
        } catch (error) {
            console.error(error);
        }
    };

the console.log() of the selectedDataVideos is :

Array (1) 0 Object

buffer: {type: "Buffer", data: Array}

name: "butterfly slow motion [oAI-OqTmJj4].mp4"

Later I transform the videos into a blob using this method and safe the result into a usestate const [tempUrls, settempUrls] = useState([]); , here a snapshot of it :

const blob = new Blob([video.buffer.data], { type: "video/mp4" });
        console.log("Videoslide 2 blob")
        console.log(blob)
        const url = URL.createObjectURL(blob);
        return {name:video.name,url:url};

The blobs are saved in a usestate const [tempUrls, settempUrls] = useState([]); The blob itself looks like this :

[Log] Blob {size: 14484621, type: "video/mp4", slice: function, stream: function, text: function, …}

An index the tempUrls looks finished like this :

[Log] {name: "butterfly slow motion [oAI-OqTmJj4].mp4", url: "blob:http:// localhost:8081/ed893b3d-298f-40c4-b4c0-1c3ac688aa43"}

The space in http:// localhost is for removing the hyperlink here. For display the video and to play it I have this :

{tempUrls.map(video =>
        <div key={video.name} style={{ flex: 2, padding: "15px 20px" }}>
          <video
            src={video.url}
            controls
            type="video/mp4"
          >
          </video>

Only the control placeholder is displayed but I can't play the video. Also, when I open the web page in Firefox this is displayed. "No video with supported format and MIME type found". But I am not clear where exactly I made the mistake when converting. Actually I converted the array buffer to a blob of type mp4/video and then to a URL. Then saved it as object {filename, url} in a usestate and from this usestate the videos should be played/displayed.

Does anyone here possibly see the error, I've been sitting on it a bit longer without finding it. The video itself is not corrupted, ive stored it in a docker next cloud server and can play it there without problems.

Upvotes: 1

Views: 590

Answers (1)

Vl ad
Vl ad

Reputation: 31

Solved it by using

import { Buffer } from "buffer"; 

from npm to convert the arraybuffer.

                let buffer = Buffer.from(item.buffer.data);
                const blob = new Blob([buffer], { type: "video/mp4" });
                const url = URL.createObjectURL(blob);
                result.push({ name: item.name, url: url });

Upvotes: 2

Related Questions