Skip to content
Snippets Groups Projects
Commit cd96b388 authored by fkiefer's avatar fkiefer
Browse files

OO-2483 Add error handling to transcoding and admin GUI

parent dedd46c7
No related branches found
No related tags found
No related merge requests found
Showing
with 391 additions and 33 deletions
......@@ -34,6 +34,9 @@ import org.olat.resource.OLATResource;
public interface VideoTranscoding extends CreateInfo {
public static final int TRANSCODING_STATUS_WAITING = -1;
public static final int TRANSCODING_STATUS_DONE = 100;
public static final int TRANSCODING_STATUS_INEFFICIENT = -2;
public static final int TRANSCODING_STATUS_ERROR = -3;
public static final int TRANSCODING_STATUS_TIMEOUT = -4;
public static final String FORMAT_MP4 = "mp4";
public static final String TRANSCODER_LOCAL = "Local HandBrakeCLI";
......
......@@ -58,6 +58,8 @@ public class TranscodingQueueTableModel extends DefaultFlexiTableDataModel<Trans
case size: return video.getSize();
case format: return video.getFormat();
case delete: return video.getDeleteLink();
case retranscode: return video.getRetranscodeLink();
case failureReason: return video.getFailureReason();
default: return "";
}
}
......@@ -70,7 +72,9 @@ public class TranscodingQueueTableModel extends DefaultFlexiTableDataModel<Trans
dimension("quality.table.header.dimension"),
size("quality.table.header.size"),
format("quality.table.header.format"),
delete("quality.table.header.delete");
delete("quality.table.header.delete"),
retranscode("queue.table.header.retranscode"),
failureReason("queue.table.failure.reason");
private final String i18nKey;
......
......@@ -31,7 +31,7 @@ import org.olat.core.gui.components.form.flexible.elements.FormLink;
*/
public class TranscodingQueueTableRow {
private String resid;
private FormLink resid;
private String displayname;
private FormLink creator;
private Date creationDate;
......@@ -39,6 +39,8 @@ public class TranscodingQueueTableRow {
private String size;
private String format;
private FormLink deleteLink;
private FormLink retranscodeLink;
private String failureReason;
protected FormUIFactory uifactory = FormUIFactory.getInstance();
......@@ -53,7 +55,7 @@ public class TranscodingQueueTableRow {
* @param format the format
* @param deleteLink FormLink for delete row and corresponding Videodata or null if no deleteLink should be shown
*/
public TranscodingQueueTableRow(String resid, String displayname, Date creationDate, FormLink resolution, String dimension, String size, String format, FormLink deleteLink) {
public TranscodingQueueTableRow(FormLink resid, String displayname, Date creationDate, FormLink resolution, String dimension, String size, String format, FormLink deleteLink) {
this.resid = resid;
this.displayname = displayname;
this.creator = resolution;
......@@ -65,6 +67,15 @@ public class TranscodingQueueTableRow {
if(deleteLink != null) this.deleteLink = deleteLink;
}
public String getFailureReason() {
return failureReason;
}
public void setFailureReason(String failureReason) {
this.failureReason = failureReason;
}
public Date getCreationDate(){
return creationDate;
}
......@@ -81,11 +92,11 @@ public class TranscodingQueueTableRow {
this.displayname = displayname;
}
public String getResid(){
public FormLink getResid(){
return resid;
}
public void setResid(String resid){
public void setResid(FormLink resid){
this.resid = resid;
}
......@@ -128,5 +139,13 @@ public class TranscodingQueueTableRow {
public void setDeleteLink(FormLink deleteLink) {
this.deleteLink = deleteLink;
}
public FormLink getRetranscodeLink() {
return retranscodeLink;
}
public void setRetranscodeLink(FormLink retranscodeLink) {
this.retranscodeLink = retranscodeLink;
}
}
......@@ -29,16 +29,18 @@ public class TranscodingRow {
private int resolution;
private int sumVideos;
private int missingTranscodings;
private int failedTranscodings;
private int numberTranscodings;
private boolean allTranscoded;
public TranscodingRow(int resolution, int numberTranscodings, int sumVideos, boolean mayTranscode) {
public TranscodingRow(int resolution, int numberTranscodings, int failedTranscodings, int sumVideos, boolean mayTranscode) {
super();
this.resolution = resolution;
this.numberTranscodings = numberTranscodings;
this.sumVideos = sumVideos;
this.missingTranscodings = sumVideos - numberTranscodings;
this.allTranscoded = numberTranscodings < sumVideos && mayTranscode;
this.missingTranscodings = sumVideos - numberTranscodings - failedTranscodings;
this.failedTranscodings = failedTranscodings;
this.allTranscoded = numberTranscodings + failedTranscodings < sumVideos && mayTranscode;
}
......@@ -74,9 +76,17 @@ public class TranscodingRow {
public void setNumberTranscodings(int numberTranscodings) {
this.numberTranscodings = numberTranscodings;
}
public int getFailedTranscodings() {
return failedTranscodings;
}
public void setFailedTranscodings(int failedTranscodings) {
this.failedTranscodings = failedTranscodings;
}
public int getMissingTranscodings() {
return missingTranscodings;
return missingTranscodings >= 0 ? missingTranscodings : 0;
}
public void setMissingTranscodings(int missingTranscodings) {
......
......@@ -52,6 +52,7 @@ public class TranscodingTableModel extends DefaultFlexiTableDataModel<Transcodin
case resolutions: return translator.translate("quality.resolution." + resolution.getResolution());
case sumVideos: return resolution.getSumVideos();
case numberTranscodings: return resolution.getNumberTranscodings();
case failedTranscodings: return resolution.getFailedTranscodings();
case missingTranscodings: return resolution.getMissingTranscodings();
case transcode: return resolution.isAllTranscoded();
case delete: return resolution.getNumberTranscodings() > 0;
......@@ -63,6 +64,7 @@ public class TranscodingTableModel extends DefaultFlexiTableDataModel<Transcodin
resolutions("quality.table.header.resolution"),
sumVideos("sum.video"),
numberTranscodings("number.transcodings"),
failedTranscodings("number.transcodings.failed"),
missingTranscodings("missing.transcodings"),
transcode("quality.transcode"),
delete("quality.delete");
......
......@@ -40,12 +40,13 @@ public class VideoAdminController extends BasicController {
private final SegmentViewComponent segmentView;
private Link adminSetLink, adminListLink, adminTranscodingLink;
private Link adminSetLink, adminListLink, adminTranscodingLink, adminErrorLink;
private VelocityContainer mainVC;
private VideoAdminSetController adminSetController;
private VideoAdminListController adminListController;
private VideoAdminTranscodingController adminTranscodingController;
private VideoAdminErrorController adminErrorController;
public VideoAdminController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl);
......@@ -57,6 +58,8 @@ public class VideoAdminController extends BasicController {
segmentView.addSegment(adminSetLink, true);
adminListLink = LinkFactory.createLink("tab.admin.list", mainVC, this);
segmentView.addSegment(adminListLink, false);
adminErrorLink = LinkFactory.createLink("tab.admin.error", mainVC, this);
segmentView.addSegment(adminErrorLink, false);
adminTranscodingLink = LinkFactory.createLink("tab.admin.transcoding", mainVC, this);
segmentView.addSegment(adminTranscodingLink, false);
......@@ -80,11 +83,21 @@ public class VideoAdminController extends BasicController {
doOpenAdminList(ureq);
} else if (clickedLink == adminTranscodingLink){
doOpenTranscodingAdmin(ureq);
} else if (clickedLink == adminErrorLink) {
doOpenErrorAdmin(ureq);
}
}
}
}
private void doOpenErrorAdmin(UserRequest ureq) {
if(adminErrorController == null) {
adminErrorController = new VideoAdminErrorController(ureq, getWindowControl());
listenTo(adminErrorController);
}
mainVC.put("segmentCmp", adminErrorController.getInitialComponent());
}
private void doOpenAdminConfig(UserRequest ureq) {
if(adminSetController == null) {
adminSetController = new VideoAdminSetController(ureq, getWindowControl());
......
/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.modules.video.ui;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.olat.NewControllerFactory;
import org.olat.basesecurity.BaseSecurity;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.form.flexible.FormItem;
import org.olat.core.gui.components.form.flexible.FormItemContainer;
import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement;
import org.olat.core.gui.components.form.flexible.elements.FormLink;
import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
import org.olat.core.gui.components.form.flexible.impl.FormEvent;
import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
import org.olat.core.id.Identity;
import org.olat.course.CorruptedCourseException;
import org.olat.modules.video.VideoManager;
import org.olat.modules.video.VideoTranscoding;
import org.olat.modules.video.ui.TranscodingQueueTableModel.TranscodingQueueTableCols;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryService;
import org.olat.repository.handlers.RepositoryHandler;
import org.olat.repository.handlers.RepositoryHandlerFactory;
import org.olat.user.HomePageConfig;
import org.olat.user.HomePageDisplayController;
import org.olat.user.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial Date: 31.01.2017
* The Class VideoAdminErrorController.
* @author fkiefer fabian.kiefer@frentix.com
*
* shows a list of all FAILED transcoding orders
*/
public class VideoAdminErrorController extends FormBasicController {
private TranscodingQueueTableModel tableModel;
private FlexiTableElement tableEl;
private FormItemContainer formLayout;
private FormLink refreshButton;
private CloseableModalController closeableModalController;
private HomePageDisplayController homePageDisplayController;
private int counter = 0;
@Autowired
private VideoManager videoManager;
@Autowired
private UserManager userManager;
@Autowired
private RepositoryService repositoryService;
@Autowired
private BaseSecurity baseSecurity;
@Autowired
private RepositoryHandlerFactory repositoryHandlerFactory;
public VideoAdminErrorController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl,"transcoding_queue");
FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.resid));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.displayname));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.failureReason));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.creator));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.creationDate));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.dimension));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.format));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.retranscode));
columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingQueueTableCols.delete));
tableModel = new TranscodingQueueTableModel(columnsModel, getTranslator());
initForm(ureq);
}
@Override
protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
this.formLayout = formLayout;
setFormTitle("number.transcodings");
setFormDescription("number.transcodings");
setFormContextHelp("Portfolio template: Administration and editing#configuration");
initTable();
}
private void initTable () {
List<VideoTranscoding> videoTranscodings = videoManager.getFailedVideoTranscodings();
List<TranscodingQueueTableRow> rows = new ArrayList<>();
for (VideoTranscoding videoTranscoding : videoTranscodings) {
String title = videoManager.getDisplayTitleForResolution(videoTranscoding.getResolution(), getTranslator());
String resid = String.valueOf(videoTranscoding.getVideoResource().getResourceableId());
FormLink resourceLink = uifactory.addFormLink("res_" + counter++, "viewResource", resid, resid, flc, Link.LINK + Link.NONTRANSLATED);
resourceLink.setUserObject(videoTranscoding);
FormLink deleteLink = uifactory.addFormLink("del_" + counter++, "deleteQuality", "quality.delete", "quality.delete", flc, Link.LINK);
deleteLink.setUserObject(videoTranscoding);
deleteLink.setIconLeftCSS("o_icon o_icon_delete_item o_icon-fw");
FormLink retranscodeLink = uifactory.addFormLink("trans_" + counter++, "retranscode", "queue.retranscode", "queue.retranscode", flc, Link.LINK);
retranscodeLink.setUserObject(videoTranscoding);
retranscodeLink.setIconLeftCSS("o_icon o_icon_refresh o_icon-fw");
String failureReason = "";
if (videoTranscoding.getStatus() == VideoTranscoding.TRANSCODING_STATUS_INEFFICIENT) {
failureReason = translate("transcoding.inefficient");
} else if (videoTranscoding.getStatus() == VideoTranscoding.TRANSCODING_STATUS_ERROR) {
failureReason = translate("transcoding.error");
} else if (videoTranscoding.getStatus() == VideoTranscoding.TRANSCODING_STATUS_TIMEOUT) {
failureReason = translate("transcoding.timeout");
}
RepositoryEntry videoRe = repositoryService.loadByResourceKey(videoTranscoding.getVideoResource().getKey());
if (videoRe == null) continue;
String displayname = videoRe.getDisplayname();
String initialAuthor = videoRe.getInitialAuthor();
String fullName = userManager.getUserDisplayName(initialAuthor);
FormLink authorLink = uifactory.addFormLink("author_" + counter++, "viewAuthor",
fullName, fullName, flc, Link.LINK + Link.NONTRANSLATED);
authorLink.setUserObject(initialAuthor);
Date creationDate = videoTranscoding.getCreationDate();
TranscodingQueueTableRow transcodingrow = new TranscodingQueueTableRow(resourceLink, displayname, creationDate, authorLink,
title, null, videoTranscoding.getFormat(), deleteLink);
transcodingrow.setFailureReason(failureReason);
transcodingrow.setRetranscodeLink(retranscodeLink);
rows.add(transcodingrow);
}
tableModel.setObjects(rows);
if (formLayout.hasFormComponent(tableEl)){
formLayout.remove(tableEl);
}
if (formLayout.hasFormComponent(refreshButton)){
formLayout.remove(refreshButton);
}
tableEl = uifactory.addTableElement(getWindowControl(), "queue", tableModel, getTranslator(), formLayout);
tableEl.setCustomizeColumns(false);
tableEl.setNumOfRowsEnabled(false);
refreshButton = uifactory.addFormLink("button.refresh", formLayout,Link.BUTTON);
refreshButton.setIconLeftCSS("o_icon o_icon_refresh o_icon-fw");
}
@Override
public void event(UserRequest ureq, Component source, Event event) {
super.event(ureq, source, event);
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if (source == homePageDisplayController || source == closeableModalController){
cleanUp();
}
super.event(ureq, source, event);
}
@Override
protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
if (source instanceof FormLink && ((FormLink) source).getCmd().equals("deleteQuality")) {
FormLink link = (FormLink) source;
VideoTranscoding videoTranscoding = (VideoTranscoding) link.getUserObject();
videoManager.deleteVideoTranscoding(videoTranscoding);
} else if (source instanceof FormLink && ((FormLink) source).getCmd().equals("viewAuthor")) {
showUserInfo(ureq, baseSecurity.findIdentityByName((String) source.getUserObject()));
} else if (source instanceof FormLink && ((FormLink) source).getCmd().equals("retranscode")) {
FormLink link = (FormLink) source;
VideoTranscoding videoTranscoding = (VideoTranscoding) link.getUserObject();
videoManager.retranscodeFailedVideoTranscoding(videoTranscoding);
} else if (source instanceof FormLink && ((FormLink) source).getCmd().equals("viewResource")) {
FormLink link = (FormLink) source;
VideoTranscoding videoTranscoding = (VideoTranscoding) link.getUserObject();
launch(ureq, videoTranscoding);
}
initTable();
}
@Override
protected void formOK(UserRequest ureq) {
}
@Override
protected void doDispose() {
}
protected void launch(UserRequest ureq, VideoTranscoding videoTranscoding) {
RepositoryEntry videoRe = repositoryService.loadByResourceKey(videoTranscoding.getVideoResource().getKey());
try {
RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler("FileResource.VIDEO");
if(handler != null) {
String businessPath = "[RepositoryEntry:" + videoRe.getKey() + "]";
if(!NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl())) {
tableEl.reloadData();
}
}
} catch (CorruptedCourseException e) {
logError("Course corrupted: " + videoRe.getKey(), e);
showError("cif.error.corrupted");
}
}
/**
* Method to open the users visiting card in a new tab. Public to call it also from the parent controller
* @param ureq
*/
public void showUserInfo(UserRequest ureq, Identity userID) {
homePageDisplayController = new HomePageDisplayController(ureq, getWindowControl(), userID, new HomePageConfig());
closeableModalController = new CloseableModalController(getWindowControl(), translate("close"),
homePageDisplayController.getInitialComponent(), true, translate("video.contact"));
listenTo(closeableModalController);
closeableModalController.activate();
}
private void cleanUp(){
closeableModalController.deactivate();
removeAsListenerAndDispose(closeableModalController);
closeableModalController = null;
homePageDisplayController = null;
}
}
......@@ -23,6 +23,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.olat.NewControllerFactory;
import org.olat.basesecurity.BaseSecurity;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
......@@ -42,11 +43,14 @@ import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
import org.olat.core.id.Identity;
import org.olat.core.util.Formatter;
import org.olat.course.CorruptedCourseException;
import org.olat.modules.video.VideoManager;
import org.olat.modules.video.VideoTranscoding;
import org.olat.modules.video.ui.TranscodingQueueTableModel.TranscodingQueueTableCols;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryService;
import org.olat.repository.handlers.RepositoryHandler;
import org.olat.repository.handlers.RepositoryHandlerFactory;
import org.olat.user.HomePageConfig;
import org.olat.user.HomePageDisplayController;
import org.olat.user.UserManager;
......@@ -80,6 +84,8 @@ public class VideoAdminListController extends FormBasicController {
private RepositoryService repositoryService;
@Autowired
private BaseSecurity baseSecurity;
@Autowired
protected RepositoryHandlerFactory repositoryHandlerFactory;
public VideoAdminListController(UserRequest ureq, WindowControl wControl) {
super(ureq, wControl,"transcoding_queue");
......@@ -112,18 +118,15 @@ public class VideoAdminListController extends FormBasicController {
List<VideoTranscoding> videoTranscodings = videoManager.getVideoTranscodingsPendingAndInProgress();
List<TranscodingQueueTableRow> rows = new ArrayList<>();
for(VideoTranscoding videoTranscoding:videoTranscodings){
for (VideoTranscoding videoTranscoding : videoTranscodings) {
String title = videoManager.getDisplayTitleForResolution(videoTranscoding.getResolution(), getTranslator());
String resid = String.valueOf(videoTranscoding.getVideoResource().getResourceableId());
FormLink previewVersionLink = uifactory.addFormLink("res_" + counter++, "viewQuality", resid, resid, flc, Link.LINK + Link.NONTRANSLATED);
FormLink resourceLink = uifactory.addFormLink("res_" + counter++, "viewResource", resid, resid, flc, Link.LINK + Link.NONTRANSLATED);
resourceLink.setUserObject(videoTranscoding);
FormLink deleteLink = uifactory.addFormLink("del_" + counter++, "deleteQuality", "quality.delete", "quality.delete", flc, Link.LINK);
deleteLink.setUserObject(videoTranscoding);
deleteLink.setIconLeftCSS("o_icon o_icon_delete_item o_icon-fw");
previewVersionLink.setUserObject(videoTranscoding);
if (videoTranscoding.getStatus() < VideoTranscoding.TRANSCODING_STATUS_DONE) {
previewVersionLink.setEnabled(false);
}
deleteLink.setIconLeftCSS("o_icon o_icon_delete_item o_icon-fw");
String fileSize = "";
if (videoTranscoding.getSize() != 0) {
fileSize = Formatter.formatBytes(videoTranscoding.getSize());
......@@ -133,6 +136,7 @@ public class VideoAdminListController extends FormBasicController {
fileSize = translate("transcoding.processing") + ": " + videoTranscoding.getStatus() + "%";
}
RepositoryEntry videoRe = repositoryService.loadByResourceKey(videoTranscoding.getVideoResource().getKey());
if (videoRe == null) continue;
String displayname = videoRe.getDisplayname();
String initialAuthor = videoRe.getInitialAuthor();
String fullName = userManager.getUserDisplayName(initialAuthor);
......@@ -140,7 +144,7 @@ public class VideoAdminListController extends FormBasicController {
fullName, fullName, flc, Link.LINK + Link.NONTRANSLATED);
authorLink.setUserObject(initialAuthor);
Date creationDate = videoTranscoding.getCreationDate();
rows.add(new TranscodingQueueTableRow(resid, displayname, creationDate, authorLink, title, fileSize, videoTranscoding.getFormat(), deleteLink));
rows.add(new TranscodingQueueTableRow(resourceLink, displayname, creationDate, authorLink, title, fileSize, videoTranscoding.getFormat(), deleteLink));
}
tableModel.setObjects(rows);
......@@ -158,8 +162,6 @@ public class VideoAdminListController extends FormBasicController {
refreshButton = uifactory.addFormLink("button.refresh", formLayout,Link.BUTTON);
refreshButton.setIconLeftCSS("o_icon o_icon_refresh o_icon-fw");
}
@Override
......@@ -183,6 +185,10 @@ public class VideoAdminListController extends FormBasicController {
videoManager.deleteVideoTranscoding(videoTranscoding);
} else if (source instanceof FormLink && ((FormLink) source).getCmd().equals("viewAuthor")) {
showUserInfo(ureq, baseSecurity.findIdentityByName((String) source.getUserObject()));
} else if (source instanceof FormLink && ((FormLink) source).getCmd().equals("viewResource")) {
FormLink link = (FormLink) source;
VideoTranscoding videoTranscoding = (VideoTranscoding) link.getUserObject();
launch(ureq, videoTranscoding);
}
initTable();
};
......@@ -197,6 +203,23 @@ public class VideoAdminListController extends FormBasicController {
}
private void launch(UserRequest ureq, VideoTranscoding videoTranscoding) {
RepositoryEntry videoRe = repositoryService.loadByResourceKey(videoTranscoding.getVideoResource().getKey());
try {
RepositoryHandler handler = repositoryHandlerFactory.getRepositoryHandler("FileResource.VIDEO");
if(handler != null) {
String businessPath = "[RepositoryEntry:" + videoRe.getKey() + "]";
if(!NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl())) {
tableEl.reloadData();
}
}
} catch (CorruptedCourseException e) {
logError("Course corrupted: " + videoRe.getKey(), e);
showError("cif.error.corrupted");
}
}
/**
* Method to open the users visiting card in a new tab. Public to call it also from the parent controller
* @param ureq
......
......@@ -91,6 +91,7 @@ public class VideoAdminTranscodingController extends FormBasicController {
transcodingModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingCols.resolutions));
transcodingModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingCols.sumVideos));
transcodingModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingCols.numberTranscodings));
transcodingModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingCols.failedTranscodings));
transcodingModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingCols.missingTranscodings));
transcodingModel.addFlexiColumnModel(new DefaultFlexiColumnModel(TranscodingCols.transcode, "quality.transcode",
new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("quality.transcode"), "quality.transcode"), null)));
......@@ -122,17 +123,24 @@ public class VideoAdminTranscodingController extends FormBasicController {
List<TranscodingRow> resolutions = new ArrayList<>();
// Hardcoded same as VideoAdminSetController
int[] fixresolution = { 2160, 1080, 720, 480, 360, 240 };
Map<Integer, Integer> resCount = new HashMap<>();
for (TranscodingCount transcodingCount : videoManager.getAllVideoTranscodingsCount()) {
resCount.put(transcodingCount.getResolution(), transcodingCount.getCount());
Map<Integer, Integer> successCount = new HashMap<>();
int beginErrorCode = VideoTranscoding.TRANSCODING_STATUS_INEFFICIENT;
for (TranscodingCount transcodingCount : videoManager.getAllVideoTranscodingsCountSuccess(beginErrorCode)) {
successCount.put(transcodingCount.getResolution(), transcodingCount.getCount());
}
Map<Integer, Integer> failCount = new HashMap<>();
for (TranscodingCount transcodingCount : videoManager.getAllVideoTranscodingsCountFails(beginErrorCode)) {
failCount.put(transcodingCount.getResolution(), transcodingCount.getCount());
}
for (int i = 0; i < fixresolution.length; i++) {
int counter = 0;
for (OLATResource videoResource : nativeResolutions.keySet()) {
if (nativeResolutions.get(videoResource) >= fixresolution[i]) counter++;
}
int rescount = resCount.get(fixresolution[i]) != null ? resCount.get(fixresolution[i]) : 0;
resolutions.add(new TranscodingRow(fixresolution[i], rescount, counter, mayTranscode(fixresolution[i])));
int Scount = successCount.get(fixresolution[i]) != null ? successCount.get(fixresolution[i]) : 0;
int Fcount = failCount.get(fixresolution[i]) != null ? failCount.get(fixresolution[i]) : 0;
TranscodingRow transcodingRow = new TranscodingRow(fixresolution[i], Scount, Fcount, counter, mayTranscode(fixresolution[i]));
resolutions.add(transcodingRow);
}
if (resolutions != null){
tableModel.setObjects(resolutions);
......
......@@ -28,6 +28,7 @@ import org.olat.core.commons.services.commentAndRating.CommentAndRatingDefaultSe
import org.olat.core.commons.services.commentAndRating.CommentAndRatingSecurityCallback;
import org.olat.core.commons.services.commentAndRating.ReadOnlyCommentsSecurityCallback;
import org.olat.core.commons.services.commentAndRating.ui.UserCommentsAndRatingsController;
import org.olat.core.commons.services.image.Size;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.htmlheader.jscss.JSAndCSSComponent;
......@@ -194,6 +195,11 @@ public class VideoDisplayController extends BasicController {
mainVC.contextPut("authors", (StringHelper.containsNonWhitespace(authors) ? authors : null));
if(video != null) {
// get resolution of master video resource
Size masterResolution = videoManager.getVideoResolutionFromOLATResource(entry.getOlatResource());
String masterTitle = videoManager.getDisplayTitleForResolution(masterResolution.getHeight(), getTranslator());
String masterSize = " (" + Formatter.formatBytes(videoManager.getVideoMetadata(entry.getOlatResource()).getSize()) + ")";
boolean addMaster = true;
// Mapper for Video
String masterMapperId = "master-" + entry.getOlatResource().getResourceableId();
String masterUrl = registerCacheableMapper(ureq, masterMapperId, new VideoMediaMapper(videoManager.getMasterContainer(entry.getOlatResource())));
......@@ -213,6 +219,8 @@ public class VideoDisplayController extends BasicController {
for (VideoTranscoding videoTranscoding : videos) {
if (videoTranscoding.getStatus() == VideoTranscoding.TRANSCODING_STATUS_DONE) {
readyToPlayVideos.add(videoTranscoding);
// Check if at least one has equal height, else use master as resource
addMaster &= videoTranscoding.getHeight() < masterResolution.getHeight();
// Use the users preferred resolution or the next higher resolution
if (videoTranscoding.getResolution() >= userPreferredResolution.intValue()) {
preferredAvailableResolution = readyToPlayVideos.size() - 1;
......@@ -222,6 +230,8 @@ public class VideoDisplayController extends BasicController {
displayTitles.add(title);
}
}
mainVC.contextPut("addMaster", addMaster);
mainVC.contextPut("masterTitle", masterTitle + masterSize);
mainVC.contextPut("videos", readyToPlayVideos);
mainVC.contextPut("displayTitles", displayTitles);
mainVC.contextPut("useSourceChooser", Boolean.valueOf(readyToPlayVideos.size() > 1));
......
......@@ -124,13 +124,20 @@ public class VideoQualityTableFormController extends FormBasicController {
int height = videoTranscoding.getHeight();
String dimension = width +"x"+ height;
String fileSize = "";
if (videoTranscoding.getSize() != 0) {
int status = videoTranscoding.getStatus();
if (videoTranscoding.getSize() != 0 && status > -1) {
fileSize = Formatter.formatBytes(videoTranscoding.getSize());
} else if (videoTranscoding.getStatus() == VideoTranscoding.TRANSCODING_STATUS_WAITING) {
} else if (status == VideoTranscoding.TRANSCODING_STATUS_WAITING) {
fileSize = translate("transcoding.waiting");
} else if (videoTranscoding.getStatus() <= VideoTranscoding.TRANSCODING_STATUS_DONE){
} else if (status <= VideoTranscoding.TRANSCODING_STATUS_DONE && status > -1){
fileSize = translate("transcoding.processing") + ": " + videoTranscoding.getStatus() + "%";
}
} else if (status == VideoTranscoding.TRANSCODING_STATUS_INEFFICIENT) {
fileSize = translate("transcoding.inefficient");
} else if (status == VideoTranscoding.TRANSCODING_STATUS_ERROR) {
fileSize = translate("transcoding.error");
} else if (status == VideoTranscoding.TRANSCODING_STATUS_TIMEOUT) {
fileSize = translate("transcoding.timeout");
}
rows.add(new QualityTableRow(previewVersionLink, dimension, fileSize, videoTranscoding.getFormat(), deleteLink));
}
List<Integer> missingResolutions = videoManager.getMissingTranscodings(videoResource);
......
<div class="o_video_run o_block_large_bottom clearfix">
<div class="olatFlashMovieViewer">
<video id="$r.getId("o_vid")" width="$width" height="$height" #if($usePoster) poster="$masterUrl/poster.jpg" #end controls #if(!$hasChapters) preload="none" #end oncontextmenu="return false;" #if( $autoplay ) autoplay #end class="o_video">
#if ($videos.size() == 0 || $addMaster)
<source type="video/mp4" src="$masterUrl/video.mp4" title="$masterTitle"/>
#end
#foreach($video in $videos)
#set($position = $velocityCount - 1)
<source type="video/mp4" src="$transcodedUrl/${video.getResolution()}video.mp4" title="$displayTitles.get($position) ($r.formatBytes(${video.getSize()}))" />
#end
## Use master video file if not optimized video is found
#if ($videos.size() == 0)
<source type="video/mp4" src="$masterUrl/video.mp4" />
#end
#if( $trackfiles )
#foreach( $track in $trackfiles.keySet())
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment