diff --git a/config/schema/media_entity_audio.schema.yml b/config/schema/media_entity_audio.schema.yml
index b4a0b1b..ff0e8ce 100755
--- a/config/schema/media_entity_audio.schema.yml
+++ b/config/schema/media_entity_audio.schema.yml
@@ -5,3 +5,22 @@ media_entity.bundle.type.audio:
     source_field:
       type: string
       label: 'Audio file'
+
+field.formatter.settings.audio_player_html5:
+  type: mapping
+  label: 'HTML5 audio player formatter settings'
+  mapping:
+    audio_attributes:
+      type: string
+      label: 'Attributes to add to the audio tag'
+    provide_download_link:
+      type: boolean
+      label: 'Whether to show download link'
+
+field.formatter.settings.audio_stream_html5:
+  type: mapping
+  label: 'HTML5 audio stream player formatter settings'
+  mapping:
+    controls:
+      type: boolean
+      label: 'Whether to show controls on the audio element'
diff --git a/media_entity_audio.module b/media_entity_audio.module
index cb2f424..ef76624 100755
--- a/media_entity_audio.module
+++ b/media_entity_audio.module
@@ -11,17 +11,23 @@ use Drupal\file\Entity\File;
  * Implements hook_theme().
  */
 function media_entity_audio_theme() {
-  return array(
-    'media_audio_file_formatter' => array(
-      'variables' => array(
+  return [
+    'media_audio_file_formatter' => [
+      'variables' => [
         'file' => NULL,
         'description' => NULL,
-        'attributes' => array(),
+        'attributes' => [],
         'value' => NULL,
         'extravalue' => NULL,
-      ),
-    ),
-  );
+      ],
+    ],
+    'media_audio' => [
+      'variables' => [
+        'sources' => [],
+        'controls' => FALSE,
+      ]
+    ],
+  ];
 }
 
 /**
@@ -31,17 +37,41 @@ function media_entity_audio_preprocess_media_audio_file_formatter(&$vars) {
   $file = $vars['file'];
   $file_entity = ($file instanceof File) ? $file : File::load($file->fid);
   $url = file_create_url($file_entity->getFileUri());
-  $mimetype = $file_entity->getMimeType();
+  $vars['mimetype'] = _media_entity_audio_map_mime($file_entity->getMimeType());
+  $vars['media_link'] = $url;
+}
+
+/**
+ * Template preprocess function for media_audio template.
+ */
+function template_preprocess_media_audio(&$vars) {
+  $vars['sources'] = array_map(function ($item) {
+    return [
+      'url' => $item,
+      'type' => _media_entity_audio_map_mime(\Drupal::service('file.mime_type.guesser')->guess($item)),
+    ];
+  }, $vars['sources']);
 
-  if ($mimetype == 'audio/mpeg') {
-    $vars['mimetype'] = 'audio/mpeg';
+  if ($vars['controls']) {
+    $vars['attributes']['controls'] = 'controls';
   }
-  if ($mimetype == 'audio/x-wav') {
-    $vars['mimetype'] = 'audio/wav';
+}
+
+/**
+ * Maps mimetype to the value expected by the <audio> tag.
+ *
+ * If an unsupported mime is detected NULL will be returned instead.
+ *
+ * @return string|null
+ *   Mimetype expected by <audio> tag or NULL if not supported.
+ */
+function _media_entity_audio_map_mime($mime) {
+  if ($mime == 'audio/x-wav') {
+    return 'audio/wav';
   }
-  if ($mimetype == 'audio/ogg') {
-    $vars['mimetype'] = 'audio/ogg';
+  elseif (in_array($mime, ['audio/mpeg', 'audio/ogg'])) {
+    return $mime;
   }
-  $vars['media_link'] = $url;
 
+  return NULL;
 }
diff --git a/src/Plugin/Field/FieldFormatter/AudioStreamHTML5.php b/src/Plugin/Field/FieldFormatter/AudioStreamHTML5.php
new file mode 100644
index 0000000..7ee1f46
--- /dev/null
+++ b/src/Plugin/Field/FieldFormatter/AudioStreamHTML5.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\media_entity_audio\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Field\FormatterBase;
+
+/**
+ * Plugin implementation of the 'Audio Stream (HTML5)' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "audio_stream_html5",
+ *   label = @Translation("Audio Stream (HTML5)"),
+ *   field_types = {
+ *     "link"
+ *   }
+ * )
+ */
+class AudioStreamHTML5 extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    $settings['controls'] = TRUE;
+
+    return $settings;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $form = parent::settingsForm($form, $form_state);
+
+    $form['controls'] = [
+      '#title' => $this->t('Display controls'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->getSetting('controls'),
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = parent::settingsSummary();
+
+    if ($this->getSetting('controls')) {
+      $summary[] = $this->t('Audio controls displayed.');
+    }
+    else {
+      $summary[] = $this->t('Audio controls not displayed.');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $elements = [];
+
+    foreach ($items as $delta => $item) {
+      $elements[$delta] = [
+        '#theme' => 'media_audio',
+        '#sources' => [$item->uri],
+        '#controls' => $this->getSetting('controls'),
+      ];
+
+      // Pass field item attributes to the theme function.
+      if (isset($item->_attributes)) {
+        $elements[$delta] += ['#attributes' => []];
+        $elements[$delta]['#attributes'] += $item->_attributes;
+        // Unset field item attributes since they have been included in the
+        // formatter output and should not be rendered in the field template.
+        unset($item->_attributes);
+      }
+
+    }
+    return $elements;
+  }
+
+}
diff --git a/src/Plugin/MediaEntity/Type/Audio.php b/src/Plugin/MediaEntity/Type/Audio.php
index 1f4fa81..2317658 100755
--- a/src/Plugin/MediaEntity/Type/Audio.php
+++ b/src/Plugin/MediaEntity/Type/Audio.php
@@ -24,7 +24,7 @@ class Audio extends MediaTypeBase {
     /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
     $bundle = $form_state->getFormObject()->getEntity();
     $options = [];
-    $allowed_field_types = ['file'];
+    $allowed_field_types = ['file', 'link'];
     foreach ($this->entityFieldManager->getFieldDefinitions('media', $bundle->id()) as $field_name => $field) {
       if (in_array($field->getType(), $allowed_field_types) && !$field->getFieldStorageDefinition()->isBaseField()) {
         $options[$field_name] = $field->getLabel();
@@ -67,13 +67,6 @@ class Audio extends MediaTypeBase {
    * {@inheritdoc}
    */
   public function thumbnail(MediaInterface $media) {
-    $source_field = $this->configuration['source_field'];
-
-    /** @var \Drupal\file\FileInterface $file */
-    if ($file = $media->{$source_field}->entity) {
-      return $this->config->get('icon_base') . '/image.png';
-    }
-
     return $this->getDefaultThumbnail();
   }
 
@@ -88,6 +81,9 @@ class Audio extends MediaTypeBase {
     if (!empty($source_field) && ($file = $media->{$source_field}->entity)) {
       return $file->getFilename();
     }
+    elseif (!empty($source_field) && ($uri = $media->{$source_field}->uri)) {
+      return basename($uri);
+    }
 
     return parent::getDefaultName($media);
   }
diff --git a/templates/media-audio.html.twig b/templates/media-audio.html.twig
new file mode 100644
index 0000000..c763e23
--- /dev/null
+++ b/templates/media-audio.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an audio.
+ *
+ * Available variables:
+ * - sources: list of audio sources
+ * - attributes: HTML attributes to be applied to the list.
+ *
+ * @see template_preprocess_media_audio()
+ *
+ * @ingroup themeable
+ */
+#}
+<audio {{ attributes }}>
+  {%- for source in sources -%}
+    {%- if source.type -%}
+      <source src="{{ source.url }}" type="{{ source.type }}">
+    {%- else -%}
+      <source src="{{ source.url }}">
+    {%- endif -%}
+  {%- endfor -%}
+</audio>
