Embedded audio player with externally hosted files on Drupal

Overview

Hosting audio files on a Drupal site can turn into a costly process, between the costs to host the files, as well as the bandwidth costs if the files are listened to regularly. In order to keep costs down, hosting the files on an external service, such as Dropbox, is a preferable alternative. However, as the files are not hosted on the same server as Drupal, it takes a little additional work to get this working, that at the time of writing cannot be done purely with modules.

In this module we will put together a system in which users can paste a link to an externally hosted file into a text field, and when the item is saved, the submitted URL will be set up as the file behind an audio player.

Steps

In this tutorial, we will go over the following steps:

  1. Install some required modules
  2. Create the content type that will hold the audio players
  3. Create a custom module to tie it all together

Step 1: Install some required modules

For this tutorial you will need to enable the following modules:

Step 2: Create the content type that will hold the audio players

The first thing we need to do is to create our content type, and add the required fields to the content type. We will not cover this step in this tutorial, so if you are unsure of how to do this, take a moment to google some tutorials on how to do so.

For this tutorial, you will need to create a content type with a machine name of 'song'. After creating this content type, you need to add the following fields:

    • Type: link
    • Label: Url
    • Machine Name: field_song_url
    • Number of values: 1
    • Allowed Link type: External links only
    • Allow link text: disabled
    • Required: True (checked)
    • Type: File
    • Label: Song
    • Machine Name: field_song_file
    • Number of values: 1
    • Allowed file types: mp3
    • Required: False (un-checked)

Under Manage form display, ensure that URL is visible, and that Song is hidden.

Under Manage display, ensure that Song is visible on any display modes that you want the audio file to be playable on, and set the format to be 'Audio Player'.

Step 3: Create a custom module to tie it all together

In order to get our system working, when a node of type 'Song' is saved, we will grab the URL entered in the URL field, create a file programmatically that uses that URL as the URI for the file, and associate that file to the Song node.

In this module, we will be working with a custom module with a machine name of external_audio_embed. If you do not know how to make a custom Drupal 8 module, take a moment to review the documentation here: Creating custom modules.

To do this, the first thing we need to do is implement hook_node_presave(), where we will turn the submitted URL into a File entity in our database.

First, at the top of external_audio_embed.module, add the following:

  1. <?php
  2. use \Drupal\file\Entity\File;
  3.  
  4. function external_audio_embed_node_presave(Drupal\Core\Entity\EntityInterface $node) {
  5. // Make sure we only target nodes of type Song
  6. if($this->bundle() == 'song') {
  7. // Get the URI that the user submitted
  8. $uri = $this->get('field_song_url')->uri;
  9.  
  10. // Create a File entity with the given $uri
  11. $file = File::Create(['uri' => $uri]);
  12.  
  13. // Save the file
  14. $file->save();
  15.  
  16. // Associate the new File with the field on the node
  17. $node->field_song_file->setValue(['target_id' => $file->id()]);
  18. }
  19. }

Note that this code depends on the Remote stream wrapper module, as external URIs starting with http (or https) will not work otherwise.

Summary

With the above combinations of modules and code, users can now enter an external URL into a link field, and have that file used as the back-end to an audio field HTML5 audio player, keeping the audio files hosted externally. Happy listening!