The following steps explain creating a React SPA Container component (eaem-sites-spa-dm-video-container/components/container) extending Core Container component (core/wcm/components/container/v1/container) for Video Backgrounds and Component (eg. text) overlays...
For creating a simple SPA navigation app check this post. For product sample check adobe documentation
For configuring Dynamic Media check this post
Demo | Package Install | Github
Dynamic Media Configuration
Sync Configuration at Folder Level
Set Dynamic Media Video Profile
Video Renditions (Encodes)
Component Dialog
View as Published
Solution
<%@include file="/libs/granite/ui/global.jsp"%> <%@page session="false" import="org.apache.sling.commons.json.JSONObject"%> <%@ page import="org.apache.sling.api.SlingHttpServletRequest" %> <%@ page import="com.day.cq.dam.api.Asset" %> <%@ page import="com.day.cq.dam.api.renditions.DynamicMediaRenditionProvider" %> <%@ page import="com.day.cq.dam.api.Rendition" %> <%@ page import="java.util.HashMap" %> <%@ page import="java.util.List" %> <% response.setContentType("application/json"); SlingHttpServletRequest eaemSlingRequest = slingRequest; String contentPath = eaemSlingRequest.getRequestPathInfo().getSuffix(); Resource currentResource = eaemSlingRequest.getResourceResolver().getResource(contentPath); Asset asset = (currentResource != null ? currentResource.adaptTo(Asset.class) : null); JSONObject dynRenditions = new JSONObject(); if( (asset == null) || !(asset.getMimeType().startsWith("video/")) || (asset.getMetadata("dam:scene7ID") == null)) { dynRenditions.write(response.getWriter()); return; } DynamicMediaRenditionProvider dmRendProvider = sling.getService(DynamicMediaRenditionProvider.class); String s7Domain = String.valueOf(asset.getMetadata("dam:scene7Domain")); String scene7FileAvs = String.valueOf(asset.getMetadata("dam:scene7FileAvs")); HashMap<String, Object> rules = new HashMap<String, Object>(); rules.put("remote", true); rules.put("video", true); List<Rendition> dmRenditions = dmRendProvider.getRenditions(asset, rules); JSONObject dynRendition = new JSONObject(); String image = null, avsName = scene7FileAvs.substring(scene7FileAvs.lastIndexOf("/") + 1); dynRendition.put("url", getScene7Url(s7Domain, scene7FileAvs)); dynRendition.put("image", getRendThumbnail(s7Domain, scene7FileAvs)); dynRendition.put("name", avsName); dynRenditions.put(avsName, dynRendition); for (Rendition dmRendition : dmRenditions) { dynRendition = new JSONObject(); image = dmRendition.getPath(); if(image.endsWith(".mp4")){ image = image.substring(0, image.lastIndexOf(".mp4")); } dynRendition.put("name", dmRendition.getName()); dynRendition.put("image", getRendThumbnail(s7Domain, image)); dynRendition.put("url", getScene7Url(s7Domain, dmRendition.getPath())); dynRenditions.put(dmRendition.getName(), dynRendition); } dynRenditions.write(response.getWriter()); %> <%! private static String getScene7Url(String s7Domain, String rendPath){ return s7Domain + "/s7viewers/html5/VideoViewer.html?asset=" + rendPath; } private static String getRendThumbnail(String s7Domain, String rendPath){ return s7Domain + "/is/image/" + rendPath + "?fit=constrain,1&wid=200&hei=200"; } %>
5) Create file (nt:file) /apps/eaem-sites-spa-dm-video-container/clientlibs/clientlib-dmvideo/js.txt, add
spa-dmvideo.js
6) Create file (nt:file) /apps/eaem-sites-spa-dm-video-container/clientlibs/clientlib-dmvideo/spa-dmvideo.js, add the following code...
(function ($, $document) { var DM_VIDEO_FIELD = "./eaemDMVideo", ENCODE_SELECT = "./eaemDMEncode", DM_VIDEO_RENDS_URL = "/apps/eaem-sites-spa-dm-video-container/video-dyn-renditions/content.html"; $document.on('dialog-ready', handleVideoField); function handleVideoField(){ var $videoField = $("foundation-autocomplete[name='" + DM_VIDEO_FIELD + "']"); if(_.isEmpty($videoField)){ return; } setSelectedEncode($videoField.val()); $videoField.on("change", addEncodes); } function addEncodes(event){ var $encodeField = $("coral-select[name='" + ENCODE_SELECT + "']"), selVideoPath = event.target.value; if(_.isEmpty(selVideoPath) || _.isEmpty($encodeField)){ return; } $encodeField.find("coral-select-item").not("[value='NONE']").remove(); loadEncodesInSelect(selVideoPath); } function getCoralSelectItem(text, value, selected){ return '<coral-select-item value="' + value + '" ' + selected + '>' + text + '</coral-select-item>'; } function loadEncodesInSelect(videoPath, selectedValue){ var $encodeField = $("coral-select[name='" + ENCODE_SELECT + "']"); $.ajax(DM_VIDEO_RENDS_URL + videoPath).done(function(renditions){ _.each(renditions,function(rendition){ $encodeField.append(getCoralSelectItem(rendition.name, rendition.name, ((selectedValue == rendition.name) ? "selected" : ""))); }); }); } function setSelectedEncode(selVideoPath){ if(!selVideoPath){ return; } var dialogPath; try{ dialogPath = Granite.author.DialogFrame.currentDialog.editable.slingPath; }catch(err){ console.log("Error getting dialog path...", err); } if(!dialogPath){ return; } $.ajax(dialogPath).done(function(data){ var dmEncode = data[ENCODE_SELECT.substr(2)]; if(!dmEncode){ return; } loadEncodesInSelect(selVideoPath, dmEncode); }) } }(jQuery, jQuery(document)));
import React from 'react'; import {MapTo, withComponentMappingContext, Container, ResponsiveGrid, ComponentMapping} from '@adobe/cq-react-editable-components'; import {Helmet} from "react-helmet"; class EAEMContainer extends Container { get containerProps() { let containerProps = super.containerProps; containerProps.style = { "width": '100%', "height": '500px' }; return containerProps; } get videoDivProps() { return { "id": "eaem-dm-video-viewer", "style": { "zIndex": "0", "position": "relative" } }; } get overlayDivProps() { return { "style" : { ...{ "position": "absolute", "zIndex": "1" } , ...this.props.overlayDivStyle } }; } componentDidMount() { const timer = setInterval((() => { if(window.s7viewers){ clearInterval(timer); this.loadVideo() } }).bind(this), 500); } loadVideo(){ new window.s7viewers.VideoViewer({ "containerId": "eaem-dm-video-viewer", "params": { "asset": this.props.dmVideoEncode, "serverurl": this.props.dmServerUrl, "videoserverurl": this.props.dmVideoServerUrl } }).init(); } render() { return ( <div {...this.containerProps}> { this.props.dmVideoPath && <Helmet> <script src={ this.props.dmVideoViewerPath }></script> </Helmet> } { this.props.dmVideoPath && <div {...this.videoDivProps}> <div {...this.overlayDivProps}> { this.childComponents } { this.placeholderComponent } </div> </div> } { !this.props.dmVideoPath && <div> { this.childComponents } { this.placeholderComponent } </div> } </div> ); } } export default MapTo('eaem-sites-spa-dm-video-container/components/container')(EAEMContainer);
14) Add the following code in com.eaem.core.models.impl.EAEMDMVideoContainerModelImpl.
package com.eaem.core.models.impl; import com.adobe.cq.export.json.ContainerExporter; import com.day.cq.dam.api.Asset; import com.day.cq.wcm.foundation.model.responsivegrid.ResponsiveGrid; import com.eaem.core.models.EAEMDMVideoContainerModelExporter; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import com.adobe.cq.export.json.ComponentExporter; import javax.annotation.PostConstruct; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.models.annotations.Exporter; import org.apache.sling.models.annotations.Model; import org.apache.sling.models.annotations.injectorspecific.InjectionStrategy; import org.apache.sling.models.annotations.injectorspecific.ScriptVariable; import org.apache.sling.models.annotations.injectorspecific.ValueMapValue; import java.util.HashMap; import java.util.Map; @Model( adaptables = {SlingHttpServletRequest.class}, adapters = {ContainerExporter.class, ComponentExporter.class}, resourceType = {"eaem-sites-spa-dm-video-container/components/container"} ) @Exporter( name = "jackson", extensions = {"json"} ) @JsonSerialize(as = EAEMDMVideoContainerModelExporter.class) public class EAEMDMVideoContainerModelImpl extends ResponsiveGrid implements EAEMDMVideoContainerModelExporter{ @ScriptVariable private Resource resource; @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL) private String eaemDMVideo; @ValueMapValue(injectionStrategy = InjectionStrategy.OPTIONAL) private String eaemDMEncode; private Map<String, Object> metadata; @PostConstruct protected void initModel() { super.initModel(); if( (this.resource == null) || StringUtils.isEmpty(eaemDMVideo)) { return; } ResourceResolver resolver = this.resource.getResourceResolver(); Resource videoRes = resolver.getResource(eaemDMVideo); if(videoRes == null){ return; } metadata = videoRes.adaptTo(Asset.class).getMetadata(); } public String getDmAccountName(){ if(metadata == null){ return ""; } String fileName = String.valueOf(metadata.get("dam:scene7File")); if(StringUtils.isEmpty(fileName)){ return ""; } return fileName.substring(0, fileName.indexOf("/")); } public String getDmServerUrl() { if(metadata == null){ return ""; } return metadata.get("dam:scene7Domain") + "is/image/"; } public String getDmVideoViewerPath() { if(metadata == null){ return ""; } return metadata.get("dam:scene7Domain") + "s7viewers/html5/js/VideoViewer.js"; } public String getDmVideoServerUrl() { if(metadata == null){ return ""; } return metadata.get("dam:scene7Domain") + "is/content/"; } public Map<String, String> getOverlayDivStyle() { Map<String, String> divStyles = new HashMap<String, String>(); ValueMap vm = this.resource.getValueMap(); divStyles.put("top" , vm.get("overlayTop", "")); divStyles.put("left" , vm.get("overlayLeft", "")); divStyles.put("backgroundColor" , vm.get("overlayBGColor", "#FFFFFF")); divStyles.put("padding" , vm.get("overlayPadding", "10px 20px 10px 20px")); return divStyles; } public String getDmVideoPath() { return eaemDMVideo; } public String getDmVideoEncode() { return getDmAccountName() + "/" + eaemDMEncode; } }
No comments:
Post a Comment