[Release] [JS] Radio

I was able to hear music while a player was in the car playing a radiostation but now
if i enter the car i can hear the radiostation too. if i left the car and im outside i hear the original gta5 radios, any chance to make it work again?

2 Likes

This will always show up, no matter what port is used for FiveM, as long as the link is a .mp3, .wav, or .ogg.

doesnt work just the normal gta player

Oh, i have same error(

Thank you for the good work ,
issue found , if i enter the car i can hear the radiostation. if i left the car and im outside i hear the original gta v radio , any fix ?

Yeah I messed up another part of the config making the whole script invalid, therefore failing at the first line.

Thanks for the comment, sorry for getting back to you so late lol

2 Likes

Sometimes the radios in-game will overlap with eachother I can’t seem to figure out what causes it. Any suggestions?

Did you manage to find a way on how to do this?

anyone know if you can “turn off” stations, like i only want my custom stations on the wheel, not the non changed ones

thanks for this, it worked fine, however, is there anyway to make it play more than 1 mp3 file ?! or randomise it ?

looking for this too!

i tried to put a post linking you to the actual snippet but it got blocked, here lemme see if i can sent pictures
image

image

also the actual snippet broke the code spacing, it should look like this…

Saw some people in need of randomizing mp3 files or something like that, so I’m posting something similar so others don’t have to waste time;

So in my case i needed to randomize time in big mp3 file (about 40min duration) so it would feel like listening to radio - not starting from beginning everytime. If that’s what you need, just change this between script in index.html file:

<script>
    let customRadios;

    /**
     * Radio class containing the state of our stations.
     * Includes all methods for playing, stopping, etc.
     * @param {Array} stations Array of objects with station details.
     * @param {number} volume Number from 0.0 to 1.0
     */
    const Radio = function (stations, volume) {
        let self = this;

        self.stations = stations;
        self.volume = volume;
        self.index = 0;
    };
    Radio.prototype = {
        /**
         * Play a station with a specific index.
         * @param  {Number} index Index in the array of stations.
         */
        play: function (index) {
            let self = this;
            let sound;

            index = index !== -1 ? index : self.index;
            let station = self.stations[index];

            // If we already loaded this track, use the current one.
            // Otherwise, setup and load a new Howl.
            if (station.howl) {
				sound = station.howl = new Howl({
                    src: station.data.url,
                    html5: true, // A live stream can only be played through HTML5 Audio.
                    format: ['opus', 'ogg', 'mp3'],
                    volume: (station.data.volume || 1.0) * self.volume || 0.1,
                    loop: true, // loop if file duration ends
	                onplay: customRandomSeekTime,
                });
                //sound = station.howl;
            } else {
                sound = station.howl = new Howl({
                    src: station.data.url,
                    html5: true, // A live stream can only be played through HTML5 Audio.
                    format: ['opus', 'ogg', 'mp3'],
                    volume: (station.data.volume || 1.0) * self.volume || 0.1,
                    loop: true, // loop if file duration ends
		            onplay: customRandomSeekTime,
                });
            }
			
			function customRandomSeekTime() {
				let radijoLaikai = sound._duration; // get duration of the src
				let keistiLaikus = Math.floor(Math.random()*radijoLaikai); // randomize time from the duration
				
				sound.seek(keistiLaikus); // seek to the randomized time from the duration
			}
			
			// Begin playing the sound.
				sound.play();

            // Keep track of the index we are currently playing.
            self.index = index;
        },

        /**
         * Stop a station's live stream.
         */
        stop: function () {
            let self = this;

            // Get the Howl we want to manipulate.
            let sound = self.stations[self.index].howl;

            // Stop and unload the sound.
            if (sound && sound.state() !== "unloaded") {
                sound.unload();
            } else if (sound) {
                sound.stop();
            }
        },

        /**
         * Change stations volume.
         * @param {number} volume Number from 0.0 to 1.0
         */
        setVolume: function(volume) {
            let self = this;

            self.volume = volume;

            for (let i = 0, length = self.stations.length; i < length; i++) {
                if (self.stations[i].howl) {
                    self.stations[i].howl.volume((self.stations[i].data.volume || 1.0) * volume);
                }
            }
        }
    };

    document.addEventListener("DOMContentLoaded", () => {
        fetch("http://radio/radio:ready", { "method": "POST", "body": "{}" });

        window.addEventListener("message", (event) => {
            let item = event.data;

            switch (item.type) {
                case "create":
                    customRadios = new Radio(item.radios, item.volume);
                    break;
                case "volume":
                    if (customRadios) {
                        customRadios.setVolume(item.volume);
                    }
                    break;
                case "play":
                    if (typeof customRadios !== "undefined") {
                        let index = customRadios.stations.findIndex((radio) => {
                            return radio.name === item.radio;
                        });
                        let isNotPlaying = (customRadios.stations[index].howl && !customRadios.stations[index].howl.playing());

                        // If the station isn't already playing or it doesn't exist, play it.
                        if (isNotPlaying || !customRadios.stations[index].howl) {
                            customRadios.play(index);
                        }
                    } else {
                        fetch("http://radio/radio:ready", { "method": "POST", "body": "{}" });
                    }
                    break;
                case "stop":
                    customRadios.stop();
                    break;
            }
        });
    });
</script>

Feel free to message me if something doesn’t work, ill try to help. I tried this on build 2612 and mp3 file from website, so it should work fine :slight_smile:

just follow this video:
(38) Gta V FiveM Tutorial Custom Radio/Colored Hud/Custom Logos ENG/DEU - YouTube

SetRadioStationDisabled(‘RADIO_01_CLASS_ROCK’, true)
SetRadioStationDisabled(‘RADIO_02_POP’, true)

While this mod is still downloadable, it goes against Rockstar’s new policy on real-word things, including music and actual stations unfortunately.

Remember what you’re saying

Rockstar’s new policy not FiveM’s new TOS yet - That is still pending until a further week for more clarification if stuff like this will be against the rules.

I think it is best to hold off until CFX/FiveM clarify the R* statement for the platform as a whole

This is not a license, and it does not constitute endorsement, approval, or authorization of any third-party project. Take-Two reserves the right to object to any third-party project, or to revise, revoke and/or withdraw this statement at any time in their own discretion. This statement does not constitute a waiver of any rights that Take-Two may have with respect to third-party projects.

This does also affect FiveM, since it is a third-party project.

And as well, read the post they’ve made already. On Rockstar's recently published modding policy

Yes I know I have read it but read the part below the 4 points they made

“We will be updating our terms of service in the following week to reflect those changes and clarify on all of the above points to take away any ambiguity.”
People are waiting on this to see what they mean and what it will mean in terms of what is allowed and not allowed on the platform for the future.

Reason I suggest waiting for that cause they could say stuff like this is fine or not fine, we don’t know