Commit 14c2f0c7 authored by New Zeal's avatar New Zeal

first commit

parents
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/video_js.iml" filepath="$PROJECT_DIR$/.idea/video_js.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
This diff is collapsed.
Use the Video JS library to apply videos to html elements on your website
## Install
Unzip library from github: https://github.com/videojs/video.js
Create /libraries/video-js folder
Copy/move video.min.js and video-js.min.css into video-js folder
This library is not published as a composer package
## Add Content
Video JS items are added as content and not configuration
Go to /admin/config/user-interface/video_js/sources to add sources
The target element is the element on the page that you wish to apply the video to.
The video is prepended to the target element
{
"name": "drupal/video_js",
"type": "drupal-module",
"description": "The Video JS module enables to attach background video to site pages",
"keywords": ["Drupal"],
"license": "GPL-2.0+",
"homepage": "https://www.drupal.org/project/video_js",
"minimum-stability": "dev",
"require": {
}
}
/**
* @file
* Javascript functionality for VideoJs
*/
(function ($, Drupal, drupalSettings) {
"use strict";
Drupal.behaviors.videoJs = {
attach: function (context, settings) {
if(typeof settings.video_js != 'undefined') {
// We insert the html into the element
var element = settings.video_js.element;
var html = settings.video_js.html;
$(element).prepend(html);
var options = {};
var player = videojs('my-player', options, function onPlayerReady() {
// In this context, `this` is the player that was created by Video.js.
this.play();
// How about an event listener?
// this.on('ended', function() {
// videojs.log('Awww...over so soon?!');
// });
});
}
updateSize(element);
// set events
$(window).resize( function() {
updateSize(element);
});
}
};
function updateSize(element) {
var containerW = $(element).outerWidth() < $(window).width() ? $(element).outerWidth() : $(window).width(),
containerH = $(element).outerHeight() < $(window).height() ? $(element).outerHeight() : $(window).height(),
containerAspect = containerW/containerH;
var mediaAspect = 16/9;
var vidEl = '#my-player';
if (containerAspect < mediaAspect) {
// taller
$(vidEl)
.width(containerH*mediaAspect)
.height(containerH);
// if (!settings.shrinkable) {
$(vidEl)
.css('top',0)
.css('left',-(containerH*mediaAspect-containerW)/2)
.css('height',containerH);
// } else {
// $(vidEl)
// .css('top',-(containerW/mediaAspect-containerH)/2)
// .css('left',0)
// .css('height',containerW/mediaAspect);
// }
$(vidEl+'_html5_api')
.css('width',containerH*mediaAspect)
.css('height',containerH);
$(vidEl+'_flash_api')
.css('width',containerH*mediaAspect)
.css('height',containerH);
} else {
// wider
$(vidEl)
.width(containerW);
$(vidEl)
.css('top',-(containerW/mediaAspect-containerH)/2)
.css('left',0)
.css('height',containerW/mediaAspect);
}
}
})(jQuery, Drupal, drupalSettings);
<?php
namespace Drupal\video_js\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\file\Entity\File;
/**
* Defines the Video JS entity.
*
* @ContentEntityType(
* id = "video_js",
* label = @Translation("Video JS"),
* bundle_label = @Translation("Video JS type"),
* handlers = {
* "list_builder" = "Drupal\video_js\VideoJsListBuilder",
* "form" = {
* "default" = "Drupal\video_js\Form\VideoJsForm",
* "add" = "Drupal\video_js\Form\VideoJsForm",
* "edit" = "Drupal\video_js\Form\VideoJsForm",
* "delete" = "Drupal\video_js\Form\VideoJsDeleteForm"
* },
* },
* base_table = "video_js",
* admin_permission = "administer video js",
* entity_keys = {
* "id" = "pid",
* "label" = "label",
* "langcode" = "langcode",
* "uuid" = "uuid",
* "status" = "status"
* },
* links = {
* "canonical" = "/admin/config/user-interface/video_js/pages/{video_js}",
* "add-form" = "/admin/config/user-interface/video_js/pages/add",
* "edit-form" = "/admin/config/user-interface/video_js/pages/{video_js}/edit",
* "delete-form" = "/admin/config/user-interface/video_js/pages/{video_js}/delete",
* }
* )
*/
class VideoJs extends ContentEntityBase implements VideoJsInterface {
/**
* The Video JS ID.
*
* @var string
*/
protected $id;
/**
* The Video JS label.
*
* @var string
*/
protected $label;
/**
* The Video JS path.
*
* @var string
*/
protected $path;
/**
* {@inheritdoc}
*/
public function getPath() {
return $this->get('paths')->getvalue()[0]['value'];
}
/**
* {@inheritdoc}
*/
public function setPath($path) {
$this->path = $path;
return $this;
}
/**
* The VideoJs Source label.
*
* @var string
*/
protected $type = self::TYPE_FILE;
/**
* Get source type.
*
* @return string
* Source type.
*/
public function getType() {
return $this->type;
}
/**
* Get Link
*
* @return string
* link to file.
*/
public function getLink() {
return $this->get('link')->getValue();
}
/**
* Get the file path.
*
* @return string
* File path
*/
public function getFile() {
return $this->get('file')->getValue()[0]['target_id'];
}
/**
* Get the file format.
*
* @return string
* File format.
*/
public function getFormat() {
return $this->get('format')->getValue()[0]['value'];
}
/**
* Create the links to the video
*
* @return array
*/
public function createVideoLinks() {
if ($this->getType() == static::TYPE_FILE) {
$file = File::load($this->getFile());
return file_create_url($file->getFileUri());
}
return $this->getLink();
}
/**
* Get the target element.
*
* @return string
* File format.
*/
public function getElement() {
return $this->get('element')->getValue()[0]['value'];
}
/**
* Get the video html.
*
* @return array
* Html render array.
*/
public function getHtml() {
$renderer = \Drupal::service('renderer');
$render_array = [
'#theme' => 'video_js__video',
'#source' => $this->createVideoLinks(),
'#format' => $this->getFormat()
];
return $renderer->renderPlain($render_array);
}
/**
* Sets the source language.
*
* @param string $language
* Language code.
*/
public function setLanguage($language) {
$this->set('language', $language);
}
/**
* Sets the source created datetime.
*
* @param int $datetime
* The redirect created datetime.
*/
public function setCreated($datetime) {
$this->set('created', $datetime);
}
/**
* Gets the redirect created datetime.
*
* @return int
* The redirect created datetime.
*/
public function getCreated() {
return $this->get('created')->value;
}
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = [];
$fields['pid'] = BaseFieldDefinition::create('integer')
->setLabel(t('Id'))
->setDescription(t('The id for this source.'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);
$fields['label'] = BaseFieldDefinition::create('string')
->setLabel(t('Label'))
->setDescription(t('The label for this page.'))
->setRequired(TRUE)
->setDisplayOptions('form', array(
'type' => 'textfield',
'weight' => 1,
'settings' => array(
'format' => 'plain_text'
)
))
->setTranslatable(TRUE);
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The source UUID.'))
->setReadOnly(TRUE);
$fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language code'))
->setDescription(t('The language code.'))
->setDisplayOptions('form', array(
'type' => 'language_select',
'weight' => 2,
));
// https://drupal.stackexchange.com/questions/210610/why-doesnt-my-custom-entity-work-in-an-entity-reference-field
$fields['type'] = BaseFieldDefinition::create('list_string')
->setLabel(t('Type'))
->setDescription(t('The type of file access being used.'))
->setSettings([
'allowed_values' => ['file' => 'File', 'link' => 'Link']
])
->setRequired(TRUE)
->setCardinality(1)
->setDisplayOptions('form', array(
'type' => 'options_buttons',
'weight' => 2,
))
->setDisplayConfigurable('form', TRUE);
$fields['format'] = BaseFieldDefinition::create('list_string')
->setLabel(t('Video format'))
->setDescription(t('The video format being used.'))
->setSettings([
'allowed_values' => ['mp4' => 'MP4', 'webm' => 'WebM']
])
->setRequired(TRUE)
->setCardinality(1)
->setDisplayOptions('form', array(
'type' => 'options_buttons',
'weight' => 3,
));
$validators = array(
'file_validate_extensions' => array('mp4 webm'),
'file_validate_size' => array(file_upload_max_size()),
);
$fields['file'] = BaseFieldDefinition::create('file')
->setLabel(t('File'))
->setDescription(t('Uploaded file'))
->setSetting('upload_validators', $validators)
->setSetting('file_extensions', 'mp4 webm')
->setDisplayOptions('form', array(
'type' => 'file',
'settings' => array(
'upload_validators' => $validators,
),
'weight' => 4,
));
$fields['link'] = BaseFieldDefinition::create('string')
->setLabel(t('Link'))
->setDescription(t('The link to the video being used.'))
->setDisplayOptions('form', array(
'type' => 'link',
'weight' => 5,
));
$fields['paths'] = BaseFieldDefinition::create('string_long')
->setLabel(t('Paths (not aliases)'))
->setDescription(t('Enter paths separated by new lines. Ensure that there are no spaces before or after paths.'))
->setRequired(TRUE)
->setDisplayOptions('form', array(
'type' => 'string_long',
'weight' => 3,
));
$fields['element'] = BaseFieldDefinition::create('string')
->setLabel(t('Target Element'))
->setDescription(t('The target element within which to place the video. This element must have height and width for the video to work.'))
->setDefaultValue('body')
->setDisplayOptions('form', array(
'type' => 'link',
'weight' => 5,
));
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Enabled'))
->setDescription(t('Whether or not the source is enabled.'))
->setCardinality(1)
->setDisplayOptions('form', array(
'type' => 'boolean_checkbox',
'weight' => 3,
))
->setDisplayConfigurable('form', TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The date when the source was created.'));
return $fields;
}
}
<?php
namespace Drupal\video_js\Entity;
use Drupal\Core\Entity\ContentEntityInterface;
/**
* Provides an interface for defining VideoJs Page entities.
*/
interface VideoJsInterface extends ContentEntityInterface {
const TYPE_FILE = 'file';
const TYPE_LINK = 'link';
/**
* Get path where page will be used.
*
* @return string
* Path string.
*/
public function getPath();
/**
* Set path where page will be used.
*
* @param string $path
* Path string.
*
* @return $this
*/
public function setPath($path);
}
<?php
namespace Drupal\video_js\Entity;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
/**
* Defines a storage class for BigvieoSource entity.
*
* Control file usages.
*/
class VideoJsStorage extends SqlContentEntityStorage implements VideoJsStorageInterface {
}
<?php
namespace Drupal\video_js\Entity;
use Drupal\Core\Entity\EntityBundleListenerInterface;
use Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface;
use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
/**
* Provides an interface defining an crop storage controller.
*/
interface VideoJsStorageInterface extends SqlEntityStorageInterface, DynamicallyFieldableEntityStorageSchemaInterface, EntityBundleListenerInterface {
}
<?php
namespace Drupal\video_js\Form;
use Drupal\Core\Entity\ContentEntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
/**
* Builds the form to delete VideoJs Source entities.
*/
class VideoJsDeleteForm extends ContentEntityConfirmFormBase {
/**
* {@inheritdoc}
*/
public function getQuestion() {
return $this->t('Are you sure you want to delete %name?', ['%name' => $this->entity->label()]);
}
/**
* {@inheritdoc}
*/
public function getCancelUrl() {
return new Url('video_js.list');
}
/**
* {@inheritdoc}
*/
public function getConfirmText() {
return $this->t('Delete');
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->entity->delete();
drupal_set_message(
$this->t('content @type: deleted @label.',
[
'@type' => $this->entity->bundle(),
'@label' => $this->entity->label(),
]
)
);
$form_state->setRedirectUrl($this->getCancelUrl());
}
}
<?php
namespace Drupal\video_js\Form;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\video_js\Entity\VideoJsInterface;
class VideoJsForm extends ContentEntityForm {
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
$form['link']['#states'] = [
'visible' => [
':input[name="type"]' => ['value' => VideoJsInterface::TYPE_LINK],
],
];
$form['file']['#states'] = [
'visible' => [
':input[name="type"]' => ['value' => VideoJsInterface::TYPE_FILE],
],
];
$form['file']['widget'][0]['#upload_location'] = 'public://video_js/';
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state) {
$video_js = $this->entity;
$status = $video_js->save();
switch ($status) {
case SAVED_NEW:
drupal_set_message($this->t('Created the %label VideoJs Source.', [
'%label' => $video_js->label(),
]));
break;
default:
drupal_set_message($this->t('Saved the %label VideoJs Source.', [
'%label' => $video_js->label(),
]));
}
drupal_set_message(t('The source has been saved.'));
$form_state->setRedirect('video_js.list');
}
}
<?php
namespace Drupal\video_js;
use Drupal\video_js\Entity\VideoJsInterface;
use Drupal\Core\Entity\EntityListBuilder;
use Drupal\Core\Entity\EntityInterface;
use Drupal\file\Entity\File;
/**
* Provides a listing of BigVideo Source entities.
*/
class VideoJsListBuilder extends EntityListBuilder {
/**
* {@inheritdoc}
*/
public function buildHeader() {
$header['label'] = $this->t('Source');
$header['type'] = $this->t('Type');
$header['format'] = $this->t('Format');
$header['source'] = $this->t('Source');
$header['status'] = $this->t('Status');
$header['paths'] = $this->t('Paths');
return $header + parent::buildHeader();
}
/**
* {@inheritdoc}
*/
public function buildRow(EntityInterface $entity) {
/** @var \Drupal\video_js\Entity\VideoJsInterface $entity */
$row['label'] = $entity->label();
$type = ($entity->getType() == VideoJsInterface::TYPE_FILE) ? $this->t('File') : $this->t('Link');
$row['type'] = $type;
switch ($type) {
case 'File':
$fid = $entity->get('file')->getValue()[0]['target_id'];
$file = File::load($fid);
$source = $file->getFilename();
break;
default:
$source = $entity->get('link')->getValue()[0]['value'];
}
$row['format'] = $entity->get('format')->getValue()[0]['value'];
$row['source'] = $source;
$status = $entity->get('status')->getValue();
$row['status'] = $status ? $this->t('Enabled') : $this->t('Disabled');
$row['paths'] = $entity->get('paths')->getValue()[0]['value'];
return $row + parent::buildRow($entity);
}
}
<div class="video-js-wrapper">
<video
id="my-player"
class="video-js"
autoplay
muted
loop
webkit-playsinline
preload="auto"
{#poster="//vjs.zencdn.net/v/oceans.png"#}
data-setup='{}'>
<source src="{{ source }}" type="video/{{ format }}"></source>
{#<source src="//vjs.zencdn.net/v/oceans.mp4" type="video/mp4"></source>#}
{#<source src="//vjs.zencdn.net/v/oceans.webm" type="video/webm"></source>#}
{#<source src="//vjs.zencdn.net/v/oceans.ogv" type="video/ogg"></source>#}
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a