As of #2831944: Implement media source plugin for remote video via oEmbed, the Media module has built-in support for remote media using the oEmbed standard.
Most popular services support oEmbed for embedding third-party media assets, including YouTube, Vimeo, Twitter, Instagram, Facebook, Flickr, and so forth. Drupal core implements a basic API for interacting with oEmbed services in a standard way, and provides a plugin that supports YouTube and Vimeo out of the box.
Architecture
Drupal's oEmbed API is built on top of three new core services:
media.oembed.provider_repository
This service is responsible for fetching and storing information about all known oEmbed providers. By default, it fetches this information from https://oembed.com/providers.json. Implements \Drupal\media\OEmbed\ProviderRepositoryInterface. Each provider is represented as an instance of \Drupal\media\OEmbed\Provider.
media.oembed.url_resolver
This service translates asset URLs (for instance, https://vimeo.com/7073899) into machine-consumable resource URLs which can be used by the oEmbed system. Implements \Drupal\media\OEmbed\UrlResolverInterface. Modules may alter the resource URLs by implementing hook_oembed_resource_url_alter().
media.oembed.resource_fetcher
This service takes a machine-consumable resource URL (i.e., as returned from the URL resolver), fetches it, and parses it into an instance of \Drupal\media\OEmbed\Resource, which provides all the information needed for Drupal to display the third-party media asset. Implements \Drupal\media\OEmbed\ResourceFetcherInterface.
Security
oEmbed support inherently introduces potential security hazards -- third-party oEmbed providers can return arbitrary HTML, which may in turn contain executable JavaScript code. Therefore, you should only support oEmbed providers that you trust. Drupal also tries to mitigate the risk of XSS attacks by displaying oEmbed content in an iframe, thus limiting the possible effects of harmful JavaScript. You can configure Media to serve this iframe from an alternate domain, which helps further secure cookies and other potentially sensitive information.
Extending
In order for the media system to interact with oEmbed services, there must be a source plugin which explicitly allows those services. For example, a source plugin which can interact with Deviantart and Flickr would look something like this:
<?php
namespace Drupal\mymodule\Plugin\media\Source;
use Drupal\media\Plugin\media\Source\OEmbed;
/**
* @MediaSource(
* id = "artwork",
* label = @Translation("Artwork"),
* description = @Translation("Use artwork from Deviantart and Flickr."),
* providers = {"Deviantart.com", "Flickr"},
* allowed_field_types = {"string"},
* )
*/
class Artwork extends OEmbed {
// No need for anything in here; the base plugin can take care of typical interactions
// with external oEmbed services.
}
This could also be accomplished by implementing hook_media_source_info_alter():
<?php
/**
* Implements hook_media_source_info_alter().
*/
function mymodule_media_source_info_alter(array &$sources) {
$sources['artwork'] = [
'id' => 'artwork',
'label' => t('Artwork'),
'description' => t('Use artwork from Flickr and DeviantArt.'),
'allowed_field_types' => ['string'],
'default_thumbnail_filename' => 'no-thumbnail.png',
'providers' => ['Deviantart.com', 'Flickr'],
'class' => 'Drupal\media\Plugin\media\Source\OEmbed',
'provider' => 'mymodule',
];
}
The providers key is crucial -- it defines which oEmbed providers (i.e., third-party services) will be allowed to be used by this plugin, and the plugin must explicitly opt in to each provider. The canonical list of providers is available at https://oembed.com/providers.json. The supported_providers array must contain the names of the providers you want to support, exactly as they appear in the canonical provider list.
Comments
Soundcloud Example
Would it be possible to add a working example for Soundcloud oembed to this page?
I got adding Soundcloud
I got adding Soundcloud embeds working. Displaying them still doesn't:
Apart from that the second provider, hearthis.at, doesn't work at all.
attribute
Steps to get SoundCloud fully working
Thanks Lukas, that got us most of the way there!
Ultimately this code work:
Then the steps were:
And that resulted in the ability to create a new Node and either select from existing Remote audio or add new Remote audio via URL (the latter was not possible without specifying that 'remote_audio' should use the OEmbedForm class for adding).
It turned out that Soundcloud
It turned out that Soundcloud doesn'timplement oembed correctly. I filed a support request: https://stackoverflow.com/questions/60128665/the-soundcloud-oembed-xml-e...
attribute