Building a Real-Time Online Radio with Django and WebSockets

A simple online radio web application using Django and WebSockets
February 12, 2025 by
Building a Real-Time Online Radio with Django and WebSockets
Hamed Mohammadi
| No comments yet

In this tutorial, we'll build a web-based radio application using Django and Django Channels. This project demonstrates how to implement real-time features in Django applications using WebSocket connections.

Project Overview

Our online radio application allows users to:

  • Upload audio tracks
  • Play tracks synchronously across all connected clients
  • See what's currently playing in real-time
  • Manage tracks through an admin interface

Technical Stack

  • Django: Our web framework
  • Django Channels: For WebSocket support
  • HTML5 Audio: For playing audio files
  • Bootstrap: For responsive UI
  • JavaScript: For real-time client interactions

Key Features Implementation

1. Track Model

The foundation of our application is the Track model:

class Track(models.Model):
    title = models.CharField(max_length=200)
    artist = models.CharField(max_length=200)
    audio_file = models.FileField(upload_to="tracks/")
    uploaded_at = models.DateTimeField(auto_now_add=True)
    is_playing = models.BooleanField(default=False)

    def toggle_play(self):
        Track.objects.all().update(is_playing=False)
        self.is_playing = True
        self.save()

This model handles track metadata and playback state.

2. WebSocket Integration

We use Django Channels to handle WebSocket connections for real-time updates:

class RadioConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        await self.channel_layer.group_add("radio_group", self.channel_name)
        await self.accept()

    async def broadcast_message(self, event):
        message = event["message"]
        await self.send(text_data=json.dumps({"message": message}))

3. Real-Time Playback

The magic happens in the track list template where we handle WebSocket messages:

const socket = new WebSocket(
    'ws://' + window.location.host + '/ws/radio/'
);

socket.onmessage = function(e) {
    const data = JSON.parse(e.data);
    const message = data.message;

    if (message.action === 'play') {
        const player = document.getElementById('radio-player');
        player.src = message.track_url;
        player.play();
    }
};

Interesting Challenges

1. Synchronous Playback

One of the main challenges was ensuring synchronized playback across all clients. We solved this by:

  • Using WebSockets to broadcast play events
  • Maintaining a single "now playing" state in the database
  • Using HTML5 audio controls for consistent playback

2. Media File Handling

Proper handling of audio files required:

  • Configuring Django's media settings
  • Setting up proper file storage
  • Ensuring correct URL construction for audio files
MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media"

3. Real-Time State Management

To maintain consistency across clients, we implemented:

  • A toggle_play method to ensure only one track plays at a time
  • WebSocket broadcasts for state changes
  • Client-side state updates through WebSocket messages

Future Improvements

Some potential enhancements could include:

  1. Playlist management
  2. User authentication and personal playlists
  3. Track seeking synchronization
  4. Chat functionality for listeners
  5. Audio quality options

Lessons Learned

Building this project taught us several valuable lessons:

  1. The power of WebSockets for real-time applications
  2. Django Channels' capability for handling async operations
  3. The importance of state management in real-time applications
  4. Handling media files effectively in Django

Conclusion

This project demonstrates how Django can be used to build real-time applications beyond traditional request-response patterns. By combining Django Channels with WebSockets, we created a synchronized radio experience that updates instantly across all connected clients.

The complete code is available on GitHub, and we welcome contributions and suggestions for improvements!

Getting Started

Want to try it yourself? Here's how:

git clone https://github.com/dehongi/webradio.git
cd webradio
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver

Visit http://localhost:8000 and start broadcasting!

Building a Real-Time Online Radio with Django and WebSockets
Hamed Mohammadi February 12, 2025
Share this post
Tags
Archive

Please visit our blog at:

https://zehabsd.com/blog

A platform for Flash Stories:

https://readflashy.com

A platform for Persian Literature Lovers:

https://sarayesokhan.com

Sign in to leave a comment