{"version":3,"file":"ngx-audio-control.mjs","sources":["../../../projects/ngx-audio-control/src/helper/format-time.ts","../../../projects/ngx-audio-control/src/lib/ngx-audio-control.component.ts","../../../projects/ngx-audio-control/src/lib/ngx-audio-control.component.html","../../../projects/ngx-audio-control/src/models/play-list.ts","../../../projects/ngx-audio-control/src/ngx-audio-control.ts"],"sourcesContent":["/**\r\n * Format time in seconds as MM:SS\r\n * @param seconds number\r\n * @returns MM:SS\r\n */\r\nexport function formatTime(seconds: number) {\r\n    if (Number.isNaN(+seconds) || seconds == Infinity) {\r\n        seconds = 0; //  return 'Unknown';\r\n    }\r\n    const minutes = Math.floor(seconds / 60);\r\n    const remainingSeconds = Math.floor(seconds % 60);\r\n    return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;\r\n}","import { Component, DOCUMENT, ElementRef, Inject, Input, OnInit, ViewChild } from '@angular/core';\r\nimport { formatTime } from '../helper/format-time';\r\nimport { PlayList } from '../models/play-list';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n// svg ICONS from\r\n// https://iconstack.io/library/hugeicon\r\n\r\n@Component({\r\n    standalone: true,\r\n    selector: 'ngx-audio-control',\r\n    templateUrl: './ngx-audio-control.component.html',\r\n    styleUrls: ['./ngx-audio-control.component.scss'],\r\n    imports: [CommonModule],\r\n})\r\nexport class NgxAudioControl implements OnInit {\r\n    /**\r\n     * Show play list button\r\n     */\r\n    @Input() showList: boolean = true;\r\n    /**\r\n     * Show download button\r\n     */\r\n    @Input() download: boolean = false;\r\n    /**\r\n     * Display filename in header\r\n     */\r\n    @Input() showFileName: boolean = true;\r\n    /**\r\n     * Show speed control\r\n     */\r\n    @Input() showSpeed: boolean = true;\r\n    /**\r\n     * Show volume control\r\n     */\r\n    @Input() showVolume: boolean = true;\r\n    /**\r\n     * Display vertically or horizontally between control buttons and range seeker\r\n     */\r\n    @Input() linear: boolean = false;\r\n    /**\r\n This enumerated attribute is intended to provide a hint to the browser about what the author thinks will lead to the best user experience. It may have one of the following values:\r\n\r\n    * #### `none`:  \r\n    Indicates that the audio should not be preloaded.\r\n    #### `metadata`:\r\n    Indicates that only audio metadata (e.g. length) is fetched.\r\n    #### `auto`: \r\n    Indicates that the whole audio file can be downloaded, even if the user is not expected to use it.\r\n    \r\n    ## Usage notes:\r\n    The autoplay attribute has precedence over preload. If autoplay is specified, the browser would obviously need to start downloading the audio for playback.\r\n    The browser is not forced by the specification to follow the value of this attribute; it is a mere hint.\r\n    ## Default value is `metadata`\r\n   */\r\n    @Input() preload: 'none' | 'metadata' | 'auto' = 'metadata';\r\n\r\n    /**\r\n     * set header when duration is inifinity and require call fetch request for get duration\r\n     */\r\n    @Input() fetchHeaders: HeadersInit | undefined = undefined;\r\n    /**\r\n     * An array list of file addresses in the form of strings\r\n     */\r\n    @Input() set fileList(val: string[]) {\r\n        this.audioFiles = [];\r\n        if (!val || Array.isArray(val) == false) {\r\n            return;\r\n        }\r\n        for (let item of val) {\r\n            this.audioFiles.push({\r\n                fileAddress: item,\r\n                title: decodeURIComponent(item).replace(/\\\\/g, '/').split(/\\//g).pop() ?? 'no name',\r\n            });\r\n        }\r\n        this.initialize();\r\n    }\r\n\r\n    downloading = false;\r\n\r\n    fineName = '';\r\n    speedDisplay = '1x';\r\n    audioFiles: PlayList[] = [];\r\n\r\n    currentTime = '00:00';\r\n    totalTime = '00:00';\r\n    options = {\r\n        emptyListMessage: 'No any record',\r\n    };\r\n    togglePlayList = false;\r\n\r\n    currentAudioIndex = 0;\r\n    currentFileAddress = '';\r\n    @ViewChild('audio', { static: true }) audio!: ElementRef<HTMLAudioElement>;\r\n    seekSlider = {\r\n        min: 0,\r\n        max: Infinity,\r\n        value: 0,\r\n    };\r\n    buffering = false;\r\n    errorLoad = false;\r\n    constructor(@Inject(DOCUMENT) private _doc: Document) {}\r\n\r\n    ngOnInit(): void {\r\n        this.audio.nativeElement.onloadedmetadata = (ev) => {\r\n            this.getDuration().then((duration) => {\r\n                this.seekSlider.max = duration;\r\n                this.totalTime = formatTime(duration);\r\n            });\r\n        };\r\n\r\n        this.audio.nativeElement.onloadstart = () => {\r\n            this.buffering = true;\r\n            this.errorLoad = false;\r\n        };\r\n        this.audio.nativeElement.onloadeddata = () => {\r\n            this.buffering = false;\r\n            this.errorLoad = false;\r\n        };\r\n        this.audio.nativeElement.addEventListener(\r\n            'error',\r\n            (e) => {\r\n                this.buffering = false;\r\n                this.errorLoad = true;\r\n                var noSourcesLoaded = (e.currentTarget as any).networkState === HTMLMediaElement.NETWORK_NO_SOURCE;\r\n                if (noSourcesLoaded) console.error('player', 'could not load audio source');\r\n                else console.error('player', 'unknow error!');\r\n            },\r\n            true\r\n        );\r\n\r\n        this.audio.nativeElement.ontimeupdate = () => {\r\n            this.seekSlider.value = this.audio.nativeElement.currentTime;\r\n            this.currentTime = formatTime(this.audio.nativeElement.currentTime);\r\n        };\r\n    }\r\n\r\n    private initialize(currentAudioIndex = 0, playAfterLoad = false) {\r\n        this.speedDisplay = '1x';\r\n        this.currentTime = '00:00';\r\n        this.totalTime = '00:00';\r\n        this.currentAudioIndex = currentAudioIndex;\r\n        this.currentFileAddress = '';\r\n        this.seekSlider = {\r\n            min: 0,\r\n            max: Infinity,\r\n            value: 0,\r\n        };\r\n        this.stop();\r\n        if (this.audioFiles.length > 0 && this.audioFiles[this.currentAudioIndex]) {\r\n            this.currentFileAddress = this.audioFiles[this.currentAudioIndex].fileAddress;\r\n            this.fineName = this.audioFiles[this.currentAudioIndex].title;\r\n            this.audio.nativeElement.load();\r\n        }\r\n        if (playAfterLoad) {\r\n            this.play();\r\n        }\r\n    }\r\n\r\n    playPause() {\r\n        if (this.audio.nativeElement.paused) {\r\n            this.play();\r\n        } else {\r\n            this.stop();\r\n        }\r\n    }\r\n\r\n    play(offset = 0) {\r\n        this.audio.nativeElement.play();\r\n        if (this.seekSlider.max == Infinity) {\r\n            this.getDuration(true).then((duration) => {\r\n                this.seekSlider.max = duration;\r\n                this.totalTime = formatTime(duration);\r\n            });\r\n        }\r\n    }\r\n\r\n    stop() {\r\n        this.audio.nativeElement.pause();\r\n    }\r\n\r\n    muteUnmute() {\r\n        this.audio.nativeElement.muted = !this.audio.nativeElement.muted;\r\n    }\r\n\r\n    seekAudio(ev: Event) {\r\n        const range = ev.target as HTMLInputElement;\r\n        this.audio.nativeElement.currentTime = +range.value;\r\n    }\r\n\r\n    /**\r\n     * skip audio track by second\r\n     * @param second second is +10 or -10\r\n     */\r\n    skipTrack(second: number) {\r\n        this.seekSlider.value += second;\r\n        if (this.seekSlider.value < this.seekSlider.min) this.seekSlider.value = 0;\r\n        if (this.seekSlider.value > this.seekSlider.max) this.seekSlider.value = this.seekSlider.max;\r\n        this.audio.nativeElement.currentTime = this.seekSlider.value;\r\n        console.log(this.seekSlider.value, this.audio.nativeElement.currentTime);\r\n    }\r\n\r\n    increaseSpeed() {\r\n        const delta = 0.25;\r\n        this.audio.nativeElement.playbackRate = Math.max(0.5, this.audio.nativeElement.playbackRate + delta);\r\n        this.speedDisplay = this.audio.nativeElement.playbackRate.toFixed(2) + 'x';\r\n    }\r\n\r\n    decreaseSpeed() {\r\n        const delta = -0.25;\r\n        this.audio.nativeElement.playbackRate = Math.max(0.5, this.audio.nativeElement.playbackRate + delta);\r\n        this.speedDisplay = this.audio.nativeElement.playbackRate.toFixed(2) + 'x';\r\n    }\r\n\r\n    changeVolume(ev: Event) {\r\n        let value = (ev.target as HTMLInputElement).value;\r\n        this.audio.nativeElement.volume = +value;\r\n    }\r\n    previous() {\r\n        this.currentAudioIndex--;\r\n        if (this.currentAudioIndex < 0) {\r\n            this.currentAudioIndex = this.audioFiles.length - 1;\r\n        }\r\n        this.initialize(this.currentAudioIndex, true);\r\n    }\r\n\r\n    next() {\r\n        this.currentAudioIndex++;\r\n        if (this.currentAudioIndex >= this.audioFiles.length) {\r\n            this.currentAudioIndex = 0;\r\n        }\r\n        this.initialize(this.currentAudioIndex, true);\r\n    }\r\n\r\n    playNext() {\r\n        this.next();\r\n    }\r\n\r\n    onClickPlayList(index: number) {\r\n        this.currentAudioIndex = index;\r\n        this.initialize(this.currentAudioIndex, true);\r\n    }\r\n\r\n    downloadCurrentFile() {\r\n        if (!this.currentFileAddress) return;\r\n        this.downloading = true;\r\n        var a: any = this._doc.createElement('a');\r\n        this._doc.body.appendChild(a);\r\n        a.style = 'display: none';\r\n        a.href = this.currentFileAddress;\r\n        a.download = this.fineName;\r\n        a.click();\r\n        window.URL.revokeObjectURL(this.currentFileAddress);\r\n        a.remove();\r\n        setTimeout(() => {\r\n            this.downloading = false;\r\n        }, 1000);\r\n    }\r\n\r\n    private getDuration(play = false): Promise<number> {\r\n        return new Promise(async (resolve, reject) => {\r\n            if (Number.isInteger(+this.audio.nativeElement.duration) || (this.preload !== 'auto' && !play)) {\r\n                resolve(this.audio.nativeElement.duration);\r\n                return;\r\n            }\r\n\r\n            const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();\r\n            const audioFilePath = this.currentFileAddress;\r\n            try {\r\n                const response = await fetch(audioFilePath, {\r\n                    headers: this.fetchHeaders,\r\n                });\r\n                const arrayBuffer = await response.arrayBuffer();\r\n                audioContext.decodeAudioData(arrayBuffer, ({ duration }) => {\r\n                    audioContext.close();\r\n                    resolve(duration);\r\n                });\r\n            } catch (error) {\r\n                console.error('duration:', error);\r\n                reject(error);\r\n            }\r\n        });\r\n    }\r\n}\r\n","<div class=\"audio-player\" [class.linear]=\"linear\">\n    @if (showFileName) {\n        <span class=\"file-info\">{{ fineName }}</span>\n    }\n    <audio [preload]=\"preload\" #audio>\n        <source [src]=\"currentFileAddress\" />\n    </audio>\n    <div class=\"controls\">\n        <div class=\"time-seeker\">\n            <span>{{ currentTime }}</span>\n            <input\n                class=\"seek-slider\"\n                id=\"seekSlider\"\n                type=\"range\"\n                [min]=\"seekSlider.min\"\n                [max]=\"seekSlider.max\"\n                [value]=\"seekSlider.value\"\n                step=\".1\"\n                (input)=\"seekAudio($event)\" />\n            <span>{{ totalTime }}</span>\n            @if (buffering) {\n                <div class=\"simp-buffer\"></div>\n            }\n        </div>\n        <div class=\"buttons\">\n            <button title=\"skip track -10\" (click)=\"skipTrack(-10)\">\n                <svg viewBox=\"0 0 24 24\">\n                    <defs>\n                        <style>\n                            .num {\n                                stroke-width: 2;\n                            }\n                        </style>\n                    </defs>\n                    <path d=\"M7 9l-3 -3l3 -3\"></path>\n                    <path d=\"M15.997 17.918a6.002 6.002 0 0 0 -.997 -11.918h-11\"></path>\n                    <path class=\"num\" d=\"M6 14v6\"></path>\n                    <path class=\"num\" d=\"M9 15.5v3a1.5 1.5 0 0 0 3 0v-3a1.5 1.5 0 0 0 -3 0z\"></path>\n                </svg>\n            </button>\n\n            @if (audioFiles.length > 1) {\n                <button (click)=\"previous()\" title=\"previous\">\n                    <svg viewBox=\"0 0 24 24\">\n                        <path d=\"M20 5v14l-12 -7z\" />\n                        <path d=\"M4 5l0 14\" />\n                    </svg>\n                </button>\n            }\n\n            <button\n                (click)=\"playPause()\"\n                id=\"playPauseButton\"\n                [title]=\"errorLoad ? 'Error on load audio source' : audio.paused ? 'play' : 'pause'\"\n                [disabled]=\"errorLoad\">\n                @if (audio.paused) {\n                    <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n                        <path\n                            d=\"M18.8906 12.846C18.5371 14.189 16.8667 15.138 13.5257 17.0361C10.296 18.8709 8.6812 19.7884 7.37983 19.4196C6.8418 19.2671 6.35159 18.9776 5.95624 18.5787C5 17.6139 5 15.7426 5 12C5 8.2574 5 6.3861 5.95624 5.42132C6.35159 5.02245 6.8418 4.73288 7.37983 4.58042C8.6812 4.21165 10.296 5.12907 13.5257 6.96393C16.8667 8.86197 18.5371 9.811 18.8906 11.154C19.0365 11.7084 19.0365 12.2916 18.8906 12.846Z\" />\n                    </svg>\n                } @else {\n                    <svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n                        <path\n                            d=\"M4 7C4 5.58579 4 4.87868 4.43934 4.43934C4.87868 4 5.58579 4 7 4C8.41421 4 9.12132 4 9.56066 4.43934C10 4.87868 10 5.58579 10 7V17C10 18.4142 10 19.1213 9.56066 19.5607C9.12132 20 8.41421 20 7 20C5.58579 20 4.87868 20 4.43934 19.5607C4 19.1213 4 18.4142 4 17V7Z\" />\n                        <path\n                            d=\"M14 7C14 5.58579 14 4.87868 14.4393 4.43934C14.8787 4 15.5858 4 17 4C18.4142 4 19.1213 4 19.5607 4.43934C20 4.87868 20 5.58579 20 7V17C20 18.4142 20 19.1213 19.5607 19.5607C19.1213 20 18.4142 20 17 20C15.5858 20 14.8787 20 14.4393 19.5607C14 19.1213 14 18.4142 14 17V7Z\" />\n                    </svg>\n                }\n            </button>\n\n            @if (audioFiles.length > 1) {\n                <button (click)=\"next()\" title=\"next\">\n                    <svg viewBox=\"0 0 24 24\">\n                        <path d=\"M4 5v14l12 -7z\" />\n                        <path d=\"M20 5l0 14\" />\n                    </svg>\n                </button>\n            }\n            <button title=\"skip track +10\" (click)=\"skipTrack(+10)\">\n                <svg viewBox=\"0 0 24 24\">\n                    <defs>\n                        <style>\n                            .num {\n                                stroke-width: 2;\n                            }\n                        </style>\n                    </defs>\n                    <path d=\"M17 9l3 -3l-3 -3\" />\n                    <path d=\"M8 17.918a5.997 5.997 0 0 1 -5 -5.918a6 6 0 0 1 6 -6h11\" />\n                    <path class=\"num\" d=\"M12 14v6\" />\n                    <path class=\"num\" d=\"M15 15.5v3a1.5 1.5 0 0 0 3 0v-3a1.5 1.5 0 0 0 -3 0z\" />\n                </svg>\n            </button>\n            @if (showVolume) {\n                <div class=\"volume-control\">\n                    <button (click)=\"muteUnmute()\" id=\"muteUnmuteButton\" title=\"mute volume\">\n                        @if (audio.muted) {\n                            <svg viewBox=\"0 0 24 24\">\n                                <path\n                                    d=\"M14 14.8135V9.18646C14 6.04126 14 4.46866 13.0747 4.0773C12.1494 3.68593 11.0603 4.79793 8.88232 7.02192C7.75439 8.17365 7.11085 8.42869 5.50604 8.42869C4.10257 8.42869 3.40084 8.42869 2.89675 8.77262C1.85035 9.48655 2.00852 10.882 2.00852 12C2.00852 13.118 1.85035 14.5134 2.89675 15.2274C3.40084 15.5713 4.10257 15.5713 5.50604 15.5713C7.11085 15.5713 7.75439 15.8264 8.88232 16.9781C11.0603 19.2021 12.1494 20.3141 13.0747 19.9227C14 19.5313 14 17.9587 14 14.8135Z\" />\n                                <path d=\"M18 10L22 14M18 14L22 10\" />\n                            </svg>\n                        } @else {\n                            <svg viewBox=\"0 0 24 24\">\n                                <path\n                                    d=\"M14 14.8135V9.18646C14 6.04126 14 4.46866 13.0747 4.0773C12.1494 3.68593 11.0603 4.79793 8.88232 7.02192C7.75439 8.17365 7.11085 8.42869 5.50604 8.42869C4.10257 8.42869 3.40084 8.42869 2.89675 8.77262C1.85035 9.48655 2.00852 10.882 2.00852 12C2.00852 13.118 1.85035 14.5134 2.89675 15.2274C3.40084 15.5713 4.10257 15.5713 5.50604 15.5713C7.11085 15.5713 7.75439 15.8264 8.88232 16.9781C11.0603 19.2021 12.1494 20.3141 13.0747 19.9227C14 19.5313 14 17.9587 14 14.8135Z\" />\n                                <path d=\"M17 9C17.6254 9.81968 18 10.8634 18 12C18 13.1366 17.6254 14.1803 17 15\" />\n                                <path d=\"M20 7C21.2508 8.36613 22 10.1057 22 12C22 13.8943 21.2508 15.6339 20 17\" />\n                            </svg>\n                        }\n                    </button>\n                    <input\n                        class=\"volume-slider\"\n                        id=\"volumeSlider\"\n                        type=\"range\"\n                        min=\"0\"\n                        max=\"1\"\n                        value=\"1\"\n                        step=\"0.01\"\n                        (input)=\"changeVolume($event)\" />\n                </div>\n            }\n            @if (showSpeed) {\n                <div class=\"speed-control\">\n                    <button (click)=\"decreaseSpeed()\" title=\"descrease speed\">\n                        <svg viewBox=\"0 0 24 24\">\n                            <path d=\"M20 12L4 12\" />\n                        </svg>\n                    </button>\n                    <span class=\"speed-display\" id=\"speedDisplay\">{{ speedDisplay }}</span>\n                    <button (click)=\"increaseSpeed()\" title=\"increase speed\">\n                        <svg viewBox=\"0 0 24 24\">\n                            <path d=\"M12 4V20\" />\n                            <path d=\"M4 12H20\" />\n                        </svg>\n                    </button>\n                </div>\n            }\n            @if (showList) {\n                <button (click)=\"togglePlayList = !togglePlayList\" title=\"Play list\">\n                    <svg viewBox=\"0 0 24 24\">\n                        <path d=\"M2 3L20 3\" />\n                        <path d=\"M2 10L15 10\" />\n                        <path d=\"M2 17L9 17\" />\n                        <path\n                            d=\"M18.25 19C18.25 20.6569 16.8509 22 15.125 22C13.3991 22 12 20.6569 12 19C12 17.3431 13.3991 16 15.125 16C16.8509 16 18.25 17.3431 18.25 19ZM18.25 19V10C18.6667 10.6 19 13.12 22 13.6\" />\n                    </svg>\n                </button>\n            }\n            @if (download) {\n                <button (click)=\"downloadCurrentFile()\" title=\"download\" [disabled]=\"downloading\">\n                    <svg viewBox=\"0 0 24 24\">\n                        <path\n                            d=\"M12 14.5L12 4.5M12 14.5C11.2998 14.5 9.99153 12.5057 9.5 12M12 14.5C12.7002 14.5 14.0085 12.5057 14.5 12\" />\n                        <path d=\"M20 16.5C20 18.982 19.482 19.5 17 19.5H7C4.518 19.5 4 18.982 4 16.5\" />\n                    </svg>\n                </button>\n            }\n        </div>\n    </div>\n</div>\n\n<!-- --------- play list -------------- -->\n@if (togglePlayList) {\n    <div class=\"play-list\" [class.linear]=\"linear\">\n        @if (audioFiles.length === 0) {\n            <div class=\"list-item disabled\">\n                {{ options.emptyListMessage }}\n            </div>\n        }\n        @for (item of audioFiles; track $index; let i = $index) {\n            <div class=\"list-item\" [class.active]=\"i == currentAudioIndex\" (click)=\"onClickPlayList(i)\">\n                {{ item.title }}\n            </div>\n        }\n    </div>\n}\n","export class PlayList {\r\n    title!: string;\r\n    fileAddress!: string;\r\n}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}