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

OO-2595 Add filter to avoid black video poster suggestions in video/poster config

parent 9fdee331
No related branches found
No related tags found
No related merge requests found
......@@ -463,4 +463,15 @@ public interface VideoManager {
*/
public boolean hasVideoMetadata(OLATResource videoResource);
/**
* get Frame at given frameNumber in video and save it in the VFSLeaf 'frame' if the image is not mostly black
*
* @param videoResource
* @param frameNumber
* @param duration
* @param frame resource
* @return true if image proposal is mostly black
*/
public abstract boolean getFrameWithFilter(OLATResource videoResource, int frameNumber, long duration, VFSLeaf frame);
}
\ No newline at end of file
......@@ -282,6 +282,61 @@ public class VideoManagerImpl implements VideoManager {
return false;
}
}
@Override
public boolean getFrameWithFilter(OLATResource videoResource, int frameNumber, long duration, VFSLeaf frame) {
File videoFile = ((LocalFileImpl) getMasterVideoFile(videoResource)).getBasefile();
BufferedImage bufImg = null;
boolean imgBlack = true;
int countBlack = 0;
try (RandomAccessFile randomAccessFile = new RandomAccessFile(videoFile, "r")) {
OutputStream frameOutputStream = frame.getOutputStream(false);
FileChannel ch = randomAccessFile.getChannel();
FileChannelWrapper in = new FileChannelWrapper(ch);
FrameGrab frameGrab = new FrameGrab(in).seekToFrameSloppy(frameNumber);
bufImg = frameGrab.getFrame();
int xmin = bufImg.getMinX();
int ymin = bufImg.getMinY();
int xmax = xmin + bufImg.getWidth();
int ymax = ymin + bufImg.getHeight();
int pixelCount = bufImg.getWidth() * bufImg.getHeight();
for (int x = xmin; x < xmax; x++) {
for (int y = ymin; y < ymax; y++) {
int rgb = bufImg.getRGB(x, y);
// int alpha = (0xff000000 & rgb) >>> 24;
int r = (0x00ff0000 & rgb) >> 16;
int g = (0x0000ff00 & rgb) >> 8;
int b = (0x000000ff & rgb);
if (r < 30 && g < 30 && b < 30) {
countBlack++;
}
}
}
if (countBlack > (int) (0.7F * pixelCount)) {
imgBlack = true;
} else {
imgBlack = false;
ImageIO.write(bufImg, "JPG", frameOutputStream);
}
// avoid endless loop
if (frameNumber > duration) {
imgBlack = false;
}
// close everything to prevent resource leaks
frameOutputStream.close();
in.close();
ch.close();
return imgBlack;
} catch (Exception | AssertionError e) {
log.error("Could not get frame::" + frameNumber + " for video::" + videoFile.getAbsolutePath(), e);
return false;
}
}
/**
* get the File of the videoresource
......
......@@ -87,22 +87,39 @@ public class VideoPosterSelectionForm extends BasicController {
}
long firstThirdDuration = duration/7;
for (int x = 0; x <= duration; x += firstThirdDuration) {
for (int currentFrame = 0; currentFrame <= duration; currentFrame += firstThirdDuration) {
try {
String fileName = FILENAME_PREFIX_PROPOSAL_POSTER + x + FILENAME_POSTFIX_JPG;
VFSLeaf posterProposal = tmpContainer.createChildLeaf(fileName);
videoManager.getFrame(videoResource, x, posterProposal);
String fileName;
boolean imgBlack;
int adjust = 0;
do {
fileName = FILENAME_PREFIX_PROPOSAL_POSTER + (currentFrame+adjust) + FILENAME_POSTFIX_JPG;
VFSLeaf posterProposal = tmpContainer.createChildLeaf(fileName);
imgBlack = videoManager.getFrameWithFilter(videoResource, (currentFrame+adjust), duration, posterProposal);
int step = 24;
if (currentFrame + step <= duration) {
adjust += step;
} else {
adjust -= step;
}
// set lower bound to avoid endless loop
if (currentFrame+adjust < 0) {
// if all poster images are mostly black just take current frame
videoManager.getFrame(videoResource, currentFrame, posterProposal);
break;
}
} while (imgBlack);
VideoMediaMapper mediaMapper = new VideoMediaMapper(tmpContainer);
String mediaUrl = registerMapper(ureq, mediaMapper);
String serverUrl = Settings.createServerURI();
proposalLayout.contextPut("serverUrl", serverUrl);
Link button = LinkFactory.createButton(String.valueOf(x), proposalLayout, this);
Link button = LinkFactory.createButton(String.valueOf(currentFrame), proposalLayout, this);
button.setCustomEnabledLinkCSS("o_video_poster_selct");
button.setCustomDisplayText(translate("poster.select"));
button.setUserObject(fileName);
generatedPosters.put(mediaUrl + "/" + fileName, String.valueOf(x));
generatedPosters.put(mediaUrl + "/" + fileName, String.valueOf(currentFrame));
} catch (Exception | AssertionError e) {
logError("Error while creating poster images for video::" + videoFile.getAbsolutePath(), e);
}
......
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