Search code examples
typescriptaframe

`$s` is not a valid video, depsite having png url


I am working on an angular web project with aframe.

I have a data model that contains rectangular buttons with urls for their image (jpg, png, gif). When I try to load these textures however, I receive the following warnings:

components:texture:warn $s is not a valid video https://s3.eu-central-1.amazonaws.com/...-bed3-06ba2a75717c.png

(url shortened, notice how it is a png)

The buttons also appear black with no texture.

Here is how I create my buttons:


buttons.forEach((b: ButtonV4) => {
    const button: Entity = document.createElement("a-plane");
    const url: string = this.envService.buildURL(b.image);
    button.setAttribute("src",url);
    button.setAttribute("position",new THREE.Vector3(b.x,b.y,b.z));
    button.setAttribute("rotation",new THREE.Vector3(0,0,b.rotation));
    button.setAttribute("width",b.width);
    button.setAttribute("height",b.height);
    button.setAttribute("material", "transparent: true;");
    sceneRoot.appendChild(button);
});

Is there a way to fix this?

Edit:

I've noticed that it plays Video urls just fine. I.e. supplying a mp4 file makes it play a video as a texture.


Solution

  • The problem is my data server. The content type is set to application/octet-stream, which I can't change (Out of my reach). aframe seems to interpret this as a mp4/video file automatically.

    Since my files end with png, jpg, mp4 though, i check for the file ending and create a data url with the correct mime type.

    return this.http.get<File>(url,{responseType: "blob" as "json",headers}).pipe(
            switchMap((blob: File) => {
                return new Observable<Texture>(
                    (obs: Observer<Texture>) => {
                        const fr: FileReader = new FileReader();
                        fr.onload = (e: ProgressEvent<FileReader>) => {
                            let dataUrl: string = e.target.result as string;
                            const mime: string = this.getMimeTypeFromURL(url);
                            dataUrl = dataUrl.replace("application/octet-stream",mime);
                            obs.next(new Texture(url,dataUrl));
                        };
                        fr.onloadend = () => obs.complete();
                        fr.onabort = (e: ProgressEvent<FileReader>) => obs.error(e.target.error);
                        fr.onerror = (e: ProgressEvent<FileReader>) => obs.error(e.target.error);
                        fr.readAsDataURL(blob);
                    }
                );
            })
        );
    

    private getMimeTypeFromURL(url: string): string {
            if(url.endsWith("jpg")) {
                return "image/jpg";
            }
            if(url.endsWith("jpeg")) {
                return "image/jpg";
            }
            if(url.endsWith("png")) {
                return "image/png";
            }
            if(url.endsWith("gif")) {
                return "image/gif";
            }
            return "application/octet-stream";
        }