Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1541

SvelteKit + Capacitor: Images and Audio Not Loading in iOS Simulator

$
0
0

I'm working on a SvelteKit project with Capacitor to build a mobile app. The app should display images and play audio files. Everything works fine in the browser, but when I run the app in the iOS simulator, the images and audio files do not load. I'm able to see the names of the audio track, go to the next track I have loaded and see the names of the images in the dropdown but no functionality from either.

Project Setup:

  • SvelteKit: Using @sveltejs/adapter-static
  • Capacitor: For building the mobile app
  • Build Tool: Vite

svelte.config.js:

import adapter from '@sveltejs/adapter-static';import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';/** @type {import('@sveltejs/kit').Config} */const config = {    preprocess: vitePreprocess(),    kit: {        adapter: adapter({            pages: 'build',            assets: 'build',            fallback: 'index.html'        }),        prerender: { entries: [] }    }};export default config;

capacitor.config.ts:

import type { CapacitorConfig } from '@capacitor/cli';const config: CapacitorConfig = {    appId: 'com.example.app',    appName: 'player2',    webDir: 'build'};export default config;

src/routes/+layout.js:

export const prerender = 'auto';

Relevant code:

<script>    import { onMount } from 'svelte';    import { writable } from 'svelte/store';    // Audio Context and Nodes    let audioContext: AudioContext | null = $state(null);    let gainNode: GainNode | null = $state(null);    let audioSource: MediaElementAudioSourceNode | null = $state(null);    let wavesurfer = $state<WaveSurfer | null>(null);    // Audio Player State    let audioPlayer = $state<HTMLAudioElement | null>(null);    let isPlaying = $state(false);    let currentPlaybackTime = $state('00:00');    let totalTrackDuration = $state('00:00');    let isMuted = $state(false);    let volumeLevel = $state<number>(100);    let savedVolumeLevel = $state<number>(100);    let currentTrackPosition = $state(0);    let seekPosition = $state(0);    let seekValue = $state(0);    let isDragging = $state(false);    let divLoaded = $state(false);    let currentTrack = $state<string>('');    let tracks: Object = $state({});    let songLoaded = $state(false);    // Image State    let sortedImages: string[] = $state([]);    const imageModules = import.meta.glob('../images/*');    onMount(() => {        wavesurfer = WaveSurfer.create({            container: '#waveform',            waveColor: '#00bcd4',            progressColor: '#d946ef',            url: currentTrack,            barWidth: 1,            barGap: 0.5,            barRadius: 1,            height: 30        });        wavesurfer.setVolume(0);        wavesurfer.on('click', (newTime) => {            if (audioPlayer) {                const duration = audioPlayer.duration;                const newTimeInSeconds = newTime * duration;                audioPlayer.currentTime = newTimeInSeconds;            }        });        sortedImages = Object.keys(imageModules).sort((a, b) => {            const nameA = a.split('/images/')[1].toLowerCase();            const nameB = b.split('/images/')[1].toLowerCase();            const matchA = nameA.match(/^([a-z]+)-(\d+)/);            const matchB = nameB.match(/^([a-z]+)-(\d+)/);            if (matchA && matchB) {                const prefixCompare = matchA[1].localeCompare(matchB[1]);                if (prefixCompare !== 0) return prefixCompare;                return parseInt(matchA[2]) - parseInt(matchB[2]);            }            return nameA.localeCompare(nameB);        });        const randomIndex = Math.floor(Math.random() * sortedImages.length);        selectedImage = `/src${sortedImages[randomIndex].slice(2)}`;        tracks = import.meta.glob('/src/audio/*');        const trackKeys = Object.keys(tracks);        if (trackKeys.length > 0) {            currentTrack = trackKeys[0];            if (audioPlayer) {                audioPlayer.src = currentTrack;                audioPlayer.addEventListener('loadedmetadata',                    () => {                        if (audioPlayer) {                            totalTrackDuration = formatSecondsToMinutesSeconds(audioPlayer.duration);                            songLoaded = true;                        }                    },                    { once: true }                );            }        }    });    $effect(() => {        seekValue = isDragging ? seekPosition : currentTrackPosition;        if (audioPlayer) {            setupAudioContext();            const handleTimeUpdate = () => {                currentPlaybackTime = formatSecondsToMinutesSeconds(audioPlayer?.currentTime ?? null);                currentTrackPosition = audioPlayer?.currentTime ?? 0;                if (wavesurfer) {                    const progress = audioPlayer ? audioPlayer.currentTime / audioPlayer.duration : 0;                    wavesurfer.seekTo(progress);                }            };            const handleAudioEnded = () => {                if (activeRepeat) {                    if (audioPlayer) {                        audioPlayer.currentTime = 0;                        audioPlayer.play();                    }                    isPlaying = true;                } else {                    playNextTrack();                }            };            const handleAudioDuration = () => {                totalTrackDuration = formatSecondsToMinutesSeconds(audioPlayer?.duration ?? null);                document.documentElement.style.setProperty('--spin-duration',                    $tapeSpeeds.find((speed) => speed.isActive)?.speed +'s'                );            };            handleAudioDuration();            audioPlayer.addEventListener('timeupdate', handleTimeUpdate);            audioPlayer.addEventListener('ended', handleAudioEnded);            audioPlayer.addEventListener('loadedmetadata', handleAudioDuration);            return () => {                audioPlayer?.removeEventListener('timeupdate', handleTimeUpdate);                audioPlayer?.removeEventListener('ended', handleAudioEnded);                audioPlayer?.removeEventListener('loadedmetadata', handleAudioDuration);            };        }    });</script><img    src={selectedImage}    alt="cd canvas"    class={`max-h-48 max-w-full rounded-full object-contain ${isPlaying ? 'spin-slow' : 'spin-slow paused'}`}/><audio src={currentTrack} bind:this={audioPlayer} controls preload="auto" hidden></audio><select name="records" id="record" bind:value={selectedImage}>    {#each sortedImages as image}<option value={`/src${image.slice(2)}`}>            {image.split('../images/')[1]}</option>    {/each}</select>

I'm not too familiar with Capacitor outside of the docs and a few reddit suggestions so anything and any help is appreciated!


Viewing all articles
Browse latest Browse all 1541

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>