Installation
When you install the YouTube Connector, it is recommended to use the following folder hierarchy:
cms-install-directory
youtube-connector
youtube-connector-4.4.0-executable.conf
youtube-connector-4.4.0-executable.jar
application.properties
mediaconfig.xml
data
groovy
logs
...
Starting and Stopping
You can use init.d to start and stop the YouTube Connector. Simply create a symlink in /etc/init.d which points to the jar. It should be started by root but will use the owning user of the jar file for running the application.
To start the YouTube Connector directly as non-root user, you have to change the location of the pid and log files to a place accessible by the user. Put a .conf file with the same name as the jar alongside the jar with a content like the following:
JAVA_OPTS="-Xmx1g -Davtool.groovy.dir=/cms-install-directory/youtube-connector/groovy"
PID_FOLDER="/cms-install-directory/youtube-connector/logs/"
LOG_FOLDER="/cms-install-directory/youtube-connector/logs/"
To start the YouTube Connector invoke the youtube-connector-4.4.0-executable.jar as follows:
> cd cms-install-directory/youtube-connector
> ./youtube-connector-4.4.0-executable.jar start
To stop the YouTube Connector, enter the following:
> cd cms-install-directory/youtube-connector
> ./youtube-connector-4.4.0-executable.jar stop
For all possible options look at the Spring Boot documentation.
Document Model
For each video there must be a corresponding Sophora document. The configuration of the document type must either comply to a few rules, which are stated below, or the video document must be processed by a preprocessor script. Every time the YouTube Connector processes a video, the preprocessor script is called with the ISophoraDocument
node of the video document. The script can then change the node to match the rules used by the YouTube Connector.
Table of Files
The video files which are available for a document have to be listed in a dynamic table. Each child node representing a row of the table has to have the name avtool:file
and has to be of type avtool-nt:file
. The following properties are supported:
avtool:format
(String): The video format of the file. The YouTube Connector supports videos in different formats, e.g. MP4 hq, MP4 low, Windows Media. The configuration of the YouTube channel contains a sorted list of formats which are enabled for this channel. The YouTube connector will go through this list of formats in the given order and upload the first file that matches this format.avtool:sequence
(String): The name of the video sequence. This is usually the file name without suffix and used as the file ID for the YouTube Content ID API.avtool:name
(String): The name of the file, including the suffix. May be a sub path inside the server folders.
Property for YouTube Channel Selection
The YouTube Connector supports multiple YouTube channels, with the restriction that each video document can only be associated with one channel at a time. The video document must have a property to associate a YouTube channel (youtubeAccountPropertyName
in the mediaconfig.xml). Only videos for which a YouTube channel is set are uploaded to YouTube. The property must be a string property containing the ID of a YouTube-Channel-Configuration document, which are found in the Sophora Admin View. Usually, this property is configured as a Select Value property.
Properties for YouTube Video ID and Status Messages
After uploading a video to YouTube, the Connector writes information about the upload back to the video document. The data is appended as a yellow data with three string properties. The following information is written into the document:
- The YouTube ID of the uploaded video.
- A result code string.
- An error message in case of errors.
The actual string values of the result codes must be configured in the mediaconfig.xml to be written (deskclientFeedbackErrTypeConf
). Else only the YouTube ID is stored.
Configuration Key | Description |
---|---|
OK | The upload or update of the video was successful. |
MANY | There were multiple errors. |
TRANSPORT_MEDIASERVER | There was an error downloading the video file from the media server. |
YOUTUBE | There was an error uploading the video to YouTube. |
OTHER | Other errors, e.g. due to erroneous configuration. |
Sticky Note for Upload Result
After a successful upload or if an error occurs the YouTube Connector adds a sticky note to the document. So the editor can easily see that the file transfer is no longer running in the background. There are two types of sticky notes added: For successful transfers and for errors. Each type has its own color which can be configured in the global configuration document.
Key | Default Value |
---|---|
avtool.successColor | 129,199,132 |
avtool.errorColor | 229,115,115 |
You can disable sticky notes by setting feedback.stickyNotes.disabled = true
in the properties file.
Pre-Publishing Workflow
If you wish to use the pre-publishing workflow for video documents, the video document type must have the mixin sophora-mix:prePublishRequired
. If that is the case, the video document will go into the pre-published state when it is published by a user using the DeskClient. The YouTube Connector will then upload the video to YouTube and, once it is finished, finish the publication. If the mixin is not configured, the video is uploaded when the document is published as well, but the document will directly go into the published state.
Configuration
The YouTube Connector uses two configuration files: The "application.properties" and the "mediaconfig.xml". Samples are given below and can also be found in the distribution of the YouTube Connector in the folder "config".
application.properties
Property | Description |
---|---|
sophoraServer.host | URL to the Sophora server |
sophoraServer.username sophoraServer.password | Credentials for the Sophora server |
mediaConfig | Path to the mediaconfig.xml file. |
server.port | TCP port on which a status website is provided. If not set, a webserver is started on port 8080. Under this port you find the health endpoint of the application: http://server-address:port/health |
digest.dir | Directory for hashes of media files. These hashes are used to avoid unnecessary transfers of unchanged media files. |
job.store.path | Path to the file for the persistent queue. Events that trigger an operation of the YouTube Connector (e.g., publishing media documents) are added to the queue and will then be processed by the YouTube Connector. Example: queue.xml |
tagging.propertyPrefix.regexp | During tagging, this regular expression distinguishes between references to Sophora properties and normal, static text. Example: ^(your-prefix:|sophora:).*$ |
tagging.scriptClassPrefix.regexp | During tagging, this regular expression distinguishes between references to Groovy scripts and normal, static text. Example: ^(scriptClass:)(.+)$ |
youtube.chunking | Enables/disables chunking ("resumable media upload protocol") during YouTube upload. Setting this to false can avoid problems with certain proxy servers. However, this has the disadvantage that during the upload, the entire media file will be buffered in memory. |
youtube.delete.event.action youtube.offline.event.action | Defines the action taken for YouTube videos for different document event types. Possible values are:
|
document.preprocessorScripts | A comma-separated list of class names. The classes have to be located in the Groovy script folder and are required to implement the interface IPreprocessorScript. The YouTube connector applies these script in the specified order to documents before processing. This way, virtual properties, which are not in the CND/repository, can be set. Because the YouTube connector expects a specific document model, a preprocessor script might be required to create the properties and child nodes, which conform to this model, on the fly. |
uploader.retry.count | If the upload of a file fails because of I/O problems, the upload can be done again the given amount of times. |
uploader.retry.waitSeconds | Time in seconds to wait between uploads if an I/O problem occured and uploader.retry.count is greater than zero. |
eventhandling.publish eventhandling.offline eventhandling.delete | Optional: Enable or disable handling of particular document event types. Default is true , meaning all event types are handled. |
akamai.fastPurge.host akamai.fastPurge.accessToken akamai.fastPurge.clientToken akamai.fastPurge.clientSecret akamai.fastPurge.ccuTagPurgeDelaySeconds akamai.fastPurge.ccuUrlPurgeDelaySeconds akamai.vod.host akamai.vod.accessToken akamai.vod.clientToken akamai.vod.clientSecret akamai.vod.vodPurgeDelaySeconds | Optional: Settings for purging assets at Akamai. Properties with prefix akamai.fastPurge are for the Akamai Fast Purge API, the prefix akamai.vod is considered for Akamai VOD purges.The properties host , accessToken , clientToken and clientSecret are used for all API calls and have to be specified individually for both the Fast Purge API and VOD purges.The properties ccuTagPurgeDelaySeconds , ccuUrlPurgeDelaySeconds , vodPurgeDelaySeconds are available since version 4.4.2. They are considered for the specific purge types and cause a delay before an asset is actually purged at Akamai. The default delay is 0 .The delay can be used when the provisioning of a video asset takes some time, to prevent that the old asset is purged before the new asset is provided. The asset will then be purged with the configured delay after the Sophora Document is published. |
oauth.redirectBaseUrl (since 4.5.3) | Optional URL which is used to create the redirect URL for OAuth2 credential authorization. Normally the URL of the YouTube Connector's web server is used to build the redirect URL. If the inferred URL is not reachable by a user it can be overridden with this setting. This URL must contain the scheme and full host domain name. A context path may be present in which case all authorizations must done via this URL. At the end of this URL the path to the endpoint of the YouTube Connector accepting auth codes will be appended. Example: https://myconnector.example.com:1234 |
Example configuration
# Connection to the Sophora Primary Server.
sophoraServer.host = http://localhost:1196
sophoraServer.username = youtubeconnector
sophoraServer.password = XXXXXXX
# URL/Path to the config for media formats and -servers.
mediaConfig = file:config/mediaconfig.xml
# Web server
server.port = 5063
# JMX
jmx.registry.port = 5060
rmi.registry.port = 5061
jmx.registry.username =
jmx.registry.password =
# Upload protocol to use for YouTube videos.
# false = the entire media content will be uploaded in a single request (not resumable)
# true = the request will use the resumable media upload protocol to upload in data chunks
# For details see https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol
youtube.chunking = true
# tries after first IO error
uploader.retry.count = 2
uploader.retry.waitSeconds = 15
# Path for the MD5 digest database.
digest.dir = /cms-install-directory/youtube-connector/digest
# Path for the persistent queue file.
job.store.path = /cms-install-directory/youtube-connector/queue.xml
# Test mode: Set to true to only log operations instead of executing them.
logonly.fileoperations = false
logonly.publishdocuments = false
# In the tagging configuration of the YouTube channel configuration, values with these prefixes are considered to be
# property references.
tagging.propertyPrefix.regexp = ^(example:|sophora:|youtube.).*$
# In the tagging configuration of the YouTube channel configuration, values with these prefixes are considered to be
# references to Groovy tagging scripts.
tagging.scriptClassPrefix.regexp = ^(scriptClass:)(.+)$
# Groovy scripts (comma-separated) that can modify the document before processing
document.preprocessorScripts =
# Path of the proposal section, path elements must be separated by ';'.
# When a transport error occurs, a proposal will be created in this section.
# Leave empty to not create proposals.
proposalsection.path =
mediaconfig.xml
The mediaconfig.xml file (location set by mediaConfig property in the application.properties file) describes the document types processed by the YouTube Connector and available media formats. It also contains the global YouTube configuration.
The source of the video files is the media server. It is defined as a ServerDescription
. The transporterFactory
determines the protocol for transferring files. Possible protocols include SFTP (SSH), FTP, FTPS, Akamai NetStorage Usage API and local file system. For locating the files a pattern can be used to form the path on the server. The full path consists of three parts:
- The "baseDir" set in the
ServerDescription
. The interpretation depends on the used protocol especially for relative paths. - The "formatDirectoryMapping" provides further parts to the directory.
- The file name is retrieved from the Sophora document as described above.
After putting the parts together the following placeholders will be resolved in a path like /data/flashmedia/streams/ndr/%1$tY/%1$tm%1$td/{sophora_id}/TV-20130603-1637-5342.mp4
:
Name | Example | Description |
---|---|---|
Date pattern | %1$tY/%1$tm%1$td | A Java format string that formats the date contained in the sequence name. In the configuration the property "dateRegex" must be set to extract a date from the sequence name. |
Sequence name | {sequencename} | The sequence name of the current file that is being processed as provided in the document. |
File name | {filename} | The file name of the current file that is being processed as provided in the document. Note that the file name is automatically appended to the path on the server. |
Sophora ID | {sophora_id} | The ID of the Sophora document from which the current file was retrieved. |
Example Configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--####################################################################
Document type and media formats
#################################################################### -->
<!-- List of document types -->
<util:list id="documentDescriptionList">
<!-- Video -->
<bean class="com.subshell.sophora.avtool.api.MediaDocumentDescription">
<property name="formats">
<set>
<value>youtube</value>
</set>
</property>
<!-- Only events for this document type are handled. -->
<property name="nodeTypeName" value="example-nt:video" />
<!-- Optional: Name of a playout channel. The presence of a document on this channel corresponds to the visibility of
the media files on YouTube. -->
<property name="playoutChannelName" value="YouTube" />
<!-- Optional: Name of property that has the duration of the video. Format must be [[hours:]minutes:]seconds[.SSS]. Only
used for captions if an intro/opener of this type is prepended to the video to be uploaded. -->
<property name="durationPropertyName" value="example:duration" />
</bean>
</util:list>
<!-- Feedback to DeskClient. Map: error type to error string (you can use a select value for readable labels). -->
<util:map id="deskclientFeedbackErrTypeConf">
<entry key="TRANSPORT_MEDIASERVER" value="transport_mediaserver" />
<entry key="YOUTUBE" value="youtube" />
<entry key="OTHER" value="other" />
<entry key="MANY" value="many" />
<entry key="OK" value="ok" />
</util:map>
<!--####################################################################
Sources for video files
#################################################################### -->
<bean id="localTransporter" class="com.subshell.sophora.avtool.transporter.LocalFSTransporterFactory" />
<util:list id="mediaServerDescriptionList">
<bean class="com.subshell.sophora.avtool.api.ServerDescription">
<!-- pre-defined: defaultTransporterFactory (SFTP), ftpTransporterFactory, ftpsTransporterFactory, localTransporterFactory,
akamaiNetStorageTransporterFactory (HTTP) -->
<property name="transporterFactory" ref="defaultTransporterFactory" />
<!-- Server name from which the video files should be retrieved. When local file transfer is used, this field is only
used for logging. -->
<property name="host" value="mediaserver.example.com" />
<property name="port" value="22" />
<property name="user" value="sophora-avtool" />
<property name="password" value="changeMe" />
<property name="keyfile" value="" />
<property name="basedir" value="/data/mediasource" />
<property name="formatDirectoryMapping">
<map>
<entry key="youtube" value="." />
</map>
</property>
<!-- Optional: A regex to parse the date from a file's name, which will then be applied to all entries in the formatDirecoryMapping
that contain format specifiers, e.g. "%1$tY/%1$tm%1$td". The date in the file name must be written in the format "yyyyMMdd". -->
<property name="dateRegex" value="#?.{3}(\\d{8}).+" />
</bean>
</util:list>
<!--####################################################################
YouTube
#################################################################### -->
<!-- YouTube settings for all channels -->
<bean id="youtubeGlobalConfig" class="com.subshell.sophora.avtool.api.youtube.YoutubeConfiguration">
<!-- Property of the document that indicates which channel to use. -->
<property name="youtubeAccountPropertyName" value="example:youtubeChannel" />
<!-- The YouTube action to take when a video document is deleted or set offline. Options are DELETE, SET_PRIVATE and DO_NOTHING
(default). -->
<property name="deleteEventAction" value="DELETE" />
<property name="offlineEventAction" value="SET_PRIVATE" />
<!-- Optional: Application for adding opener and closer to the beginning/end of video. The specific videos are configured
per channel. The local script file will be executed before each YouTube upload. It will receive the following parameters:
- path to the opener file (if present)
- path to the original video file (downloaded to a temp folder)
- path to the closer file (if present)
- path to the concatenated output file that the script must create
-->
<property name="concatVideosScript"
value="/cms-install-directory/ytc_opener_und_closer/addOpenerCloser_ffmpeg.sh" />
</bean>
<util:list id="streamingServerDescriptionList">
<!--####################################################################
Optional list of servers to upload files to. Media files can be uploaded to Akamai or similar CDN servers using ftp, sftp
and ftps. When a video document is set offline, the corresponding media files will be removed from these servers. Also
purging of files from Akamai can be configured.
#################################################################### -->
<bean class="com.subshell.sophora.avtool.api.AkamaiServerDescription">
<property name="name" value="video-cdn" />
<property name="transporterFactory" ref="sftpTransporterFactory" />
<property name="host" value="akamai.example.net" />
<property name="port" value="22" />
<property name="user" value="alice" />
<property name="password" value="secret" />
<property name="keyfile" value="" />
<!-- Base directory for all uploads -->
<property name="basedir" value="/video" />
<!-- Optional: A regex to parse the date from a file's name. -->
<property name="dateRegex" value="#?.{3}(\\d{8}).+" />
<!-- Akamai FastPurge -->
<property name="akamaiUrlPatterns">
<list>
<value>http://download.mysite.com/video/%1$tY/%1$tm%1$td/{filename}</value>
<value>http://media.mysite.com/video/%1$tY/%1$tm%1$td/{filename}</value>
</list>
</property>
<property name="akamaiTagPatterns">
<list>
<value>{filename}</value>
</list>
</property>
<!-- Akamai HLS/HDS Purge -->
<property name="akamaiRestPurgeConfiguration">
<list>
<bean class="com.subshell.sophora.avtool.api.AkamaiRestPurgeRequestConfiguration">
<property name="requestName" value="HLS" />
<property name="requestPath" value="/config-media-live/v1/vod/purge/HLS" />
<property name="manifestUrl"
value="https://mysite.akamaihd.net/i/video/%1$tY/%1$tm%1$td/{sequencename}.,webs,webm,webl,webxl,.h264.mp4.csmil/master.m3u8" />
<property name="fileNamePattern" value="%1$tY/%1$tm%1$td/{filename}" />
</bean>
</list>
</property>
<!-- Mapping of format to server path. Can use date fields parsed using the dateRegex. -->
<property name="formatDirectoryMapping">
<map>
<entry key="youtube" value="%1$tY/%1$tm%1$td" />
</map>
</property>
</bean>
</util:list>
</beans>
upload account ID
as user
and the HTTP CMS API key
as password
. The Ingest directory
is your basedir
.Playout channel
In the above MediaDocumentDescription
bean (com.subshell.sophora.avtool.api.MediaDocumentDescription
) the name of a playout channel can be set, which is optional. With this feature, files will only be uploaded to YouTube if the document is enabled in the configured playout channel, which will be checked when the document is published. You can also use the timed channel affiliation settings for an automatic upload/removal of the files.
Date Pattern Matching
In the above mediaServerDescription
bean (com.subshell.sophora.avtool.api.ServerDescription
) an optional regular expression to parse the date from file names can be given. This is useful if the files are structured according to their dates in different subfolders. The regex defines the position of the date in the file name (which must be in the format "yyyyMMdd"). Once the date has been found, it will be applied to the entries in the format directory mapping that contain format specifiers, e.g. "%1$tY/%1$tm%1$td".
Timeouts
In the above mediaServerDescription
bean (com.subshell.sophora.avtool.api.ServerDescription
) additional timeout properties can be set:
Name | Description |
---|---|
connectTimeout | Timeout (in milliseconds) to open a connection. A timeout of zero is interpreted as an infinite timeout. Default is 1 minute. |
socketTimeout | Timeout (in milliseconds) for data transfers. A timeout of zero is interpreted as an infinite timeout. Default is 5 minutes. |
Example:
<?xml version="1.0" encoding="UTF-8"?>
<bean id="mediaServerDescription" class="com.subshell.sophora.avtool.api.ServerDescription">
<property name="host" value="mediaserver" />
<property name="transporterFactory" ref="localTransporter" />
<property name="connectTimeout" value="30000" /><!-- 30 seconds -->
<property name="socketTimeout" value="600000" /><!-- 10 minutes -->
</bean>
YouTube Channel Configuration in the Sophora DeskClient
The YouTube Channels are configured directly in the Sophora Admin View, using the document type "YouTube Channel" (sophora-extension-nt:youtubeChannelConfiguration). This document type is created by the YouTube Connector when it connects to the Sophora Primary Server for the first time.
Each YouTube channel configuration document has an ID (property sophora-extension:id
). In each video, there must be a property referencing the ID of a YouTube channel document. The name of this property is defined by the property youtubeAccountPropertyName
in the global YouTube configuration in the mediaconfig.xml. If this property is not set in a video document, it will not be uploaded to YouTube.
Property | Description |
---|---|
ID | The ID used to reference this channel by the video documents. This can be an arbitrary string. |
YouTube Channel ID (optional) | Only required if the account has access to multiple channels. For determining the ID from YouTube, see https://support.google.com/youtube/answer/3250431. |
Client ID, Client secret, AuthCode | See the section on authentication. |
Video format | The first format from this list that is checked in the video document will be uploaded to YouTube. |
MIME type | This MIME type is used for all formats uploaded to YouTube. |
Title | The title of the video. |
Description | The description of the video. |
Category | The category of the video. |
Keywords | The keywords for this video. |
Visibility | If set to "private", the YouTube Connector will upload videos to YouTube, but not make them publicly available. |
Location | The location name of the video. |
Latitude, Longitude | The geo location of the video. |
Thumbnail | The name of the childnode of the video document that contains the reference to the thumbnail image of the video. |
Image variant for thumbnail | The name of the image variant that will be used for the thumbnail image of the video. If this property has not been set, the "original" image variant will be used by default. |
Teaser image overlay | The external ID of the image document that contains the overlay for the thumbnail image of the video. If left blank, no overlay image will be placed on the thumbnail image. |
Caption child node | The name of the childnode of the video document that contains the binaries of the caption. |
Name of the Caption | This name is visible to the YouTube user as an option during playback. |
Content Owner | Used to manage the rights for this channel. You must be a YouTube Partner to use this. |
Match Policy | The name of the policy which is applied to videos of other users at YouTube. |
Usage Policy | The name of the policy which is applied to own videos at YouTube. |
Service Account Id | If the Client ID does not belong to a partner account, the service account is used to access the YouTube Content ID API. For creating a service account see https://developers.google.com/youtube/partner/guides/oauth2_for_service_accounts#setup. |
Service Account Key | The private key file in PKCS#12 format (without password) to authenticate the service account. |
Intro- and Outro-Videos | If you have configured an application for concatenating videos using the property concatVideosScript in the global YouTube configuration in the mediaconfig.xml, the videos given here will be given to this application for each video processed by the YouTube Connector. Since version 4.3.0 you can also use a set of videos per video to upload which overrides this setting (see below). |
- Both the Teaser image of the video and the overlay image should be as large as possible, as the generated thumbnail image will also be used as the preview image in the embedded YouTube video player. The combined size of both images should not exceed 2 MB in total due to upload limitations on YouTube.
- Preferably, the images should follow a 16:9 aspect ratio.
- The overlay image should contain transparency and be in one of the supported image formats (.GIF or .PNG). It should also have the same dimensions as the Teaser image. For this purpose it is recommended to use a custom image variant for both images instead of the "original" image variant, that complies with the abovementioned suggestions.
For further recommendations, please also check the best practices from YouTube.
The Video Data Section
The properties in the "Video Data" section of the channel configuration define the metadata for each video that is uploaded to YouTube. Each field can either reference a property in the video document, a groovy script, or contain plain string content.
- If the property value matches the regular expression given by the property
tagging.scriptClassPrefix.regexp
in the application.properties, it references a Groovy tagging script. See Tagging Script. - If the property value matches the regular expression given by the property
tagging.propertyPrefix.regexp
in the application.properties, it is assumed to be the name of a property in the video document. - If neither regular expression matches, the value is used as-is for all videos.
YouTube Content Partner
If you are a YouTube Content partner and want to use the YouTube Content ID API to claim your videos and apply policies, you need to specify a content owner. Also additional authorization is necessary. You have two options for authenticating:
- Access the YouTube Data API and YouTube Content ID API with different accounts.
- Access the YouTube Data API and the YouTube Content ID API with a single account.
In the second case a YouTube CMS user is used to access both APIs. The given content owner is also used for the YouTube Data API to act on behalf of YouTube CMS user. If the CMS user has access to multiple channels, you need to configure the channel id, so the uploaded videos are assigned to that channel. For authentication you need to provide a Client ID with secret which has access to both APIs (no service account is used).
Intro and Outro Videos
Prior to the upload process an additional tool may concatenate intro or outro videos to the main video. The tool must be specified by the property concatVideosScript
in the global YouTube configuration in the mediaconfig.xml. A general intro and outro video for a YouTube channel can be defined in the channel configuration, where the paths to the local files of the intro and outro are set (both are optional).
It is also possible to select different intro/outro videos per uploaded video which will be used instead of the ones specified in the channel configuration. To enable this feature, it is necessary to create and publish documents of type "YouTube Packaging". They define a pair of an intro and an outro video and can be given a recognizable name.
To use the "YouTube Packaging" documents, the mixin sophora-extension-mix:introOutroSet
with the property sophora-extension:introOutroSet
is provided. The mixin and property must be added to the configuration of the video document type. Afterwards you are able to select a "YouTube Packaging" for a specific YouTube video in the document editor. Note that after uploading a video for the first time to YouTube the file will not be updated and therefore changes to the packaging are not possible afterwards.
The referenced video documents must have the same document type which is configured in the YouTube connector (with a
MediaDocumentDescription
in the mediaconfig.xml). The files must be accessible at the media server in the same manner as the videos to upload to YouTube. You can restrict the type of documents to use as intro/outro video in the the default property configuration of sophora-extension:introDocument
/sophora-extension:outroDocument
or in the node type configuration of sophora-extension-nt:introOutroSet
.Authentication (OAuth)
The YouTube Connector uses the OAuth 2.0 flow for web server applications.
- Follow the steps for obtaining authorization credentials to register the YouTube Connector with YouTube. Make sure to select the correct project at the top of the cloud console. Create an OAuth client ID of type "Web application" and give it a name. You must set "Authorized redirect URIs" to point to your installed YouTube Connector. You can get this URL from the YouTube Connector itself if you visit
http://myconnector.example.com:5063/api/oauth2/redirecturi
in your browser. Replace the servername and port if you changed it. Else use the following URL where you need to adapt the hostname and maybe port:http://myconnector.example.com:5063/api/oauth2/end/youtube
. This URL must be reachable from the browser of the authenticating user, so it must not be reachable from the internet. - When you are done, copy the "client id" and "client secret" to the YouTube channel configuration document in Sophora and publish it.
- Visit the tab "YouTube authorization" in the channel document or the URL
http://myconnector.example.com:5063/api/oauth2/start/youtube?channelId=<ID of YouTube Channel in Sophora>
using your browser. After you have accepted the access permissions requested by the YouTube Connector, the browser will send an authentication code to the YouTube connector. The Connector will now use the auth code to generate credentials for YouTube. If successful a corresponding message is displayed. The credentials are saved in the directory "~/.oauth-credentials".

Scripting
There are two kinds of Groovy scripts that can be used to customize the YouTube Connector: Tagging scripts and preprocessor scripts. Scripts of both types must be put in a folder which is configured in a Java property named "avtool.groovy.dir" (with "-Davtool.groovy.dir=/path/to/groovy/scripts" in .conf file).
Tagging Script
The content for fields in the "Video Data" section of the YouTube channel configuration document can be computed by Groovy scripts. If the content starts with the script class prefix as given by the property tagging.scriptClassPrefix.regexp
in the application.properties, e.g. "scriptClass:", the remaining portion of the string is interpreted as the name of a Groovy class. For example, if the field "Title" contains the value scriptClass:YoutubeTitle
, the Connector looks for a script defining the class "YoutubeTitle", calls its processDocument()
method and uses the result as the actual title of the YouTube video. Here is an example of a tagging script:
import com.subshell.sophora.api.content.INode;
import com.subshell.sophora.avtool.api.scripting.AbstractMediaTaggingScript;
import java.text.SimpleDateFormat;
class YoutubeTitle extends AbstractMediaTaggingScript {
String processDocument(INode doc) {
def parts = []
parts << doc.getString('your-prefix:headline')
parts << context.getSelectValueLabel(doc, 'your-prefix:broadcast')
parts << "TV"
parts.removeAll { it == null || it == '' }
return parts.join(' | ')
}
}
Preprocessor Script
Every time the YouTube Connector processes a video, the preprocessor script is called with the ISophoraDocument
node of the video document. The script can then change the node, i.e. change or add properties or child nodes. The changed document is not required to match the node type configuration of the video document, i.e., the script can add arbitrary properties, which can then be referenced by the YouTube channel configuration document. The following example shows a simple preprocessor script.
import org.slf4j.Logger
import com.subshell.sophora.api.content.INode
import com.subshell.sophora.avtool.api.scripting.IPreprocessorContext
import com.subshell.sophora.avtool.api.scripting.IPreprocessorScript
class YouTubePreprocessor implements IPreprocessorScript {
private Logger log
private IPreprocessorContext context
@Override
public void init(IPreprocessorContext context) {
log = context.logger
this.context = context
}
@Override
public void preprocess(INode video) {
// Set a fixed YouTube channel for all videos.
video.setString("your-prefix:youtubeChannelId", "channel1")
// Set a new property which can then be referenced by the channel configuration.
if (video.hasProperty("your-prefix:title")) {
video.setString("youtube:title", document.getString("your-prefix:title"))
} else {
video.setString("youtube:title", "My video")
}
// The script has access to the Sophora Client.
String description = context.sophoraClient.getDocumentByExternalId("your-special-document").getString("your-prefix:youtubeDescription")
video.setString("youtube:description", description)
}
}