Abstract
Solution
1) Encodes for video are fetched and shown in the dropdown dynamically, when a user selects a dynamic media video...
2) To get the video dynamic renditions (encodes) of an asset, create the following nt:file /apps/eaem-sites-spa-dm-video-container/video-dyn-renditions/video-dyn-renditions.jsp to return the encodes of a video as JSON (serves as a client side datasource for Encodes drop down, created in next steps...)
<%@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 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";
}
%>
3) Create /apps/eaem-sites-spa-dm-video-container/video-dyn-renditions/content and set the sling:resourceType to /apps/eaem-sites-spa-dm-video-container/video-dyn-renditions. This is the content node for fetching renditions...
http://localhost:4502/apps/eaem-sites-spa-dm-video-container/video-dyn-renditions/content.html/content/dam/experience-aem/Ayutthaya_360_VR.mp4
4) Create node /apps/eaem-sites-spa-dm-video-container/clientlibs/clientlib-dmvideo of type cq:ClientLibraryFolder, add String[] property categories with value [cq.authoring.dialog.all], String[] property dependencies with value lodash.
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 '' + text + '';
}
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)));
7) Create the component /apps/eaem-sites-spa-dm-video-container/components/container extending Core Container component core/wcm/components/container/v1/container (core container component does not provide render script for React) for the SPA Editor. In the next step we'd be creating a react render script (coded in ES6)...
Read Full Blog
Q&A
Please use this thread to ask the related questions.
Kautuk Sahni