Merge pull request #2540 from mike-esokia/PHRAS-1935_refacto_prod_video_editor
PHRAS-1935 refacto prod video tools section
@@ -41,7 +41,9 @@ gulp.task('build-common-js', function(){
|
|||||||
config.paths.src + 'vendors/jquery-contextmenu/js/jquery.contextmenu_custom.js',
|
config.paths.src + 'vendors/jquery-contextmenu/js/jquery.contextmenu_custom.js',
|
||||||
config.paths.src + 'common/js/components/common.js',
|
config.paths.src + 'common/js/components/common.js',
|
||||||
config.paths.src + 'common/js/components/tooltip.js',
|
config.paths.src + 'common/js/components/tooltip.js',
|
||||||
config.paths.src + 'common/js/components/dialog.js'
|
config.paths.src + 'common/js/components/dialog.js',
|
||||||
|
config.paths.src + 'common/js/components/utils.js',
|
||||||
|
config.paths.src + 'common/js/components/download.js',
|
||||||
];
|
];
|
||||||
return utils.buildJsGroup(commonGroup, 'common', 'common/js', debugMode);
|
return utils.buildJsGroup(commonGroup, 'common', 'common/js', debugMode);
|
||||||
});
|
});
|
||||||
|
|||||||
BIN
resources/www/common/images/icons/add-new-range-hover.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
resources/www/common/images/icons/add-new-range.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
resources/www/common/images/icons/icon-photography-hover.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
resources/www/common/images/icons/icon-photography.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
resources/www/common/images/icons/picto-add-new-range-white.png
Normal file
|
After Width: | Height: | Size: 217 B |
|
After Width: | Height: | Size: 520 B |
BIN
resources/www/common/images/icons/picto-close-window.png
Normal file
|
After Width: | Height: | Size: 247 B |
BIN
resources/www/common/images/icons/picto-delete-hover.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
resources/www/common/images/icons/picto-delete.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
BIN
resources/www/common/images/icons/picto-export-thumbnail.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 517 B |
BIN
resources/www/common/images/icons/picto-save-chapter-white.png
Normal file
|
After Width: | Height: | Size: 402 B |
BIN
resources/www/common/images/icons/save-chapter-hover.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
resources/www/common/images/icons/save-chapter.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
173
resources/www/common/js/components/download.js
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
//download.js v4.2, by dandavis; 2008-2016. [CCBY2] see http://danml.com/download.html for tests/usage
|
||||||
|
// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime
|
||||||
|
// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs
|
||||||
|
// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling.
|
||||||
|
// v4 adds AMD/UMD, commonJS, and plain browser support
|
||||||
|
// v4.1 adds url download capability via solo URL argument (same domain/CORS only)
|
||||||
|
// v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors
|
||||||
|
// https://github.com/rndme/download
|
||||||
|
|
||||||
|
(function (root, factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define([], factory);
|
||||||
|
} else if (typeof exports === 'object') {
|
||||||
|
// Node. Does not work with strict CommonJS, but
|
||||||
|
// only CommonJS-like environments that support module.exports,
|
||||||
|
// like Node.
|
||||||
|
module.exports = factory();
|
||||||
|
} else {
|
||||||
|
// Browser globals (root is window)
|
||||||
|
root.download = factory();
|
||||||
|
}
|
||||||
|
}(this, function () {
|
||||||
|
|
||||||
|
return function download(data, strFileName, strMimeType) {
|
||||||
|
|
||||||
|
var self = window, // this script is only for browsers anyway...
|
||||||
|
defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads
|
||||||
|
mimeType = strMimeType || defaultMime,
|
||||||
|
payload = data,
|
||||||
|
url = !strFileName && !strMimeType && payload,
|
||||||
|
anchor = document.createElement("a"),
|
||||||
|
toString = function (a) {
|
||||||
|
return String(a);
|
||||||
|
},
|
||||||
|
myBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString),
|
||||||
|
fileName = strFileName || "download",
|
||||||
|
blob,
|
||||||
|
reader;
|
||||||
|
myBlob = myBlob.call ? myBlob.bind(self) : Blob;
|
||||||
|
|
||||||
|
if (String(this) === "true") { //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
|
||||||
|
payload = [payload, mimeType];
|
||||||
|
mimeType = payload[0];
|
||||||
|
payload = payload[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (url && url.length < 2048) { // if no filename and no mime, assume a url was passed as the only argument
|
||||||
|
fileName = url.split("/").pop().split("?")[0];
|
||||||
|
anchor.href = url; // assign href prop to temp anchor
|
||||||
|
if (anchor.href.indexOf(url) !== -1) { // if the browser determines that it's a potentially valid url path:
|
||||||
|
var ajax = new XMLHttpRequest();
|
||||||
|
ajax.open("GET", url, true);
|
||||||
|
ajax.responseType = 'blob';
|
||||||
|
ajax.onload = function (e) {
|
||||||
|
download(e.target.response, fileName, defaultMime);
|
||||||
|
};
|
||||||
|
setTimeout(function () {
|
||||||
|
ajax.send();
|
||||||
|
}, 0); // allows setting custom ajax headers using the return:
|
||||||
|
return ajax;
|
||||||
|
} // end if valid url?
|
||||||
|
} // end if url?
|
||||||
|
|
||||||
|
|
||||||
|
//go ahead and download dataURLs right away
|
||||||
|
if (/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)) {
|
||||||
|
|
||||||
|
if (payload.length > (1024 * 1024 * 1.999) && myBlob !== toString) {
|
||||||
|
payload = dataUrlToBlob(payload);
|
||||||
|
mimeType = payload.type || defaultMime;
|
||||||
|
} else {
|
||||||
|
return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs:
|
||||||
|
navigator.msSaveBlob(dataUrlToBlob(payload), fileName) :
|
||||||
|
saver(payload); // everyone else can save dataURLs un-processed
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end if dataURL passed?
|
||||||
|
|
||||||
|
blob = payload instanceof myBlob ?
|
||||||
|
payload :
|
||||||
|
new myBlob([payload], {type: mimeType});
|
||||||
|
|
||||||
|
|
||||||
|
function dataUrlToBlob(strUrl) {
|
||||||
|
var parts = strUrl.split(/[:;,]/),
|
||||||
|
type = parts[1],
|
||||||
|
decoder = parts[2] == "base64" ? atob : decodeURIComponent,
|
||||||
|
binData = decoder(parts.pop()),
|
||||||
|
mx = binData.length,
|
||||||
|
i = 0,
|
||||||
|
uiArr = new Uint8Array(mx);
|
||||||
|
|
||||||
|
for (i; i < mx; ++i) uiArr[i] = binData.charCodeAt(i);
|
||||||
|
|
||||||
|
return new myBlob([uiArr], {type: type});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saver(url, winMode) {
|
||||||
|
|
||||||
|
if ('download' in anchor) { //html5 A[download]
|
||||||
|
anchor.href = url;
|
||||||
|
anchor.setAttribute("download", fileName);
|
||||||
|
anchor.className = "download-js-link";
|
||||||
|
anchor.innerHTML = "downloading...";
|
||||||
|
anchor.style.display = "none";
|
||||||
|
document.body.appendChild(anchor);
|
||||||
|
setTimeout(function () {
|
||||||
|
anchor.click();
|
||||||
|
document.body.removeChild(anchor);
|
||||||
|
if (winMode === true) {
|
||||||
|
setTimeout(function () {
|
||||||
|
self.URL.revokeObjectURL(anchor.href);
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
}, 66);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle non-a[download] safari as best we can:
|
||||||
|
if (/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)) {
|
||||||
|
url = url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
|
||||||
|
if (!window.open(url)) { // popup blocked, offer direct download:
|
||||||
|
if (confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")) {
|
||||||
|
location.href = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//do iframe dataURL download (old ch+FF):
|
||||||
|
var f = document.createElement("iframe");
|
||||||
|
document.body.appendChild(f);
|
||||||
|
|
||||||
|
if (!winMode) { // force a mime that will download:
|
||||||
|
url = "data:" + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
|
||||||
|
}
|
||||||
|
f.src = url;
|
||||||
|
setTimeout(function () {
|
||||||
|
document.body.removeChild(f);
|
||||||
|
}, 333);
|
||||||
|
|
||||||
|
}//end saver
|
||||||
|
|
||||||
|
|
||||||
|
if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
|
||||||
|
return navigator.msSaveBlob(blob, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.URL) { // simple fast and modern way using Blob and URL:
|
||||||
|
saver(self.URL.createObjectURL(blob), true);
|
||||||
|
} else {
|
||||||
|
// handle non-Blob()+non-URL browsers:
|
||||||
|
if (typeof blob === "string" || blob.constructor === toString) {
|
||||||
|
try {
|
||||||
|
return saver("data:" + mimeType + ";base64," + self.btoa(blob));
|
||||||
|
} catch (y) {
|
||||||
|
return saver("data:" + mimeType + "," + encodeURIComponent(blob));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blob but not URL support:
|
||||||
|
reader = new FileReader();
|
||||||
|
reader.onload = function (e) {
|
||||||
|
saver(this.result);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
/* end download() */
|
||||||
|
}));
|
||||||
@@ -1,25 +1,10 @@
|
|||||||
<div id="thumb_confirm">
|
<div id="thumb_confirm">
|
||||||
<table>
|
<img class="selected" src="{{ image }}"/>
|
||||||
<tbody>
|
<div>
|
||||||
<tr>
|
{{ 'you are about to change the representation thumbnail of your video' | trans }} : <span
|
||||||
<td>
|
style='color:#884c92'>{{ video_title }}</span>
|
||||||
<img class="selected" src="{{image}}"/>
|
</div>
|
||||||
</td>
|
<div>
|
||||||
<td>
|
{{ 'do you want to validate' | trans }}
|
||||||
<img style=" width:50px;height:80px;"src="/assets/prod/images/ThumbExtractor/question_mark.png"/>
|
</div>
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" style='text-align:left'>
|
|
||||||
{{ 'you are about to change the representation thumbnail of your video' | trans }} : <span style='color:#1B9DD0'>{{video_title}}</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2" style='text-align:left'>
|
|
||||||
{{ 'do you want to validate' | trans }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div id='prod-tool-box' class="PNB10">
|
<div id='prod-tool-box' class="PNB10 video-edit">
|
||||||
|
|
||||||
{# jquery Tabs #}
|
{# jquery Tabs #}
|
||||||
<div id="tool-tabs" class="tabs">
|
<div id="tool-tabs" class="tabs PNB">
|
||||||
{# jquery menu #}
|
{# jquery menu #}
|
||||||
<div>
|
<div>
|
||||||
<ul>
|
<ul>
|
||||||
@@ -33,108 +33,113 @@
|
|||||||
{% if selectionLength == 1 %}
|
{% if selectionLength == 1 %}
|
||||||
{% for record in records %}
|
{% for record in records %}
|
||||||
{% if record.get_type() == 'video' %}
|
{% if record.get_type() == 'video' %}
|
||||||
<div id="thumbExtractor" class="tabBox">
|
<div id="thumbExtractor">
|
||||||
<div class="PNB10 main_title">
|
|
||||||
<img src='/assets/prod/images/ThumbExtractor/camera_title.png'/>
|
|
||||||
{{ "screenshot video" | trans }}
|
|
||||||
</div>
|
|
||||||
<hr style='margin-top:25px;'/>
|
|
||||||
<div class="PNB part_title_left"></div>
|
|
||||||
|
|
||||||
<div class="PNB frame_video">
|
<div id="thumbExtractor-preview">
|
||||||
{% set outputFormats = record.getSubdfefByDeviceAndMime(null, ['image/jpeg', 'image/png']) %}
|
<div class="frame_video">
|
||||||
{% set previewHtml5 = record.getSubdfefByDeviceAndMime(constant('\\databox_subdef::DEVICE_SCREEN'), ['video/ogg', 'video/mp4', 'video/webm']) %}
|
{% set outputFormats = record.getSubdfefByDeviceAndMime(null, ['image/jpeg', 'image/png']) %}
|
||||||
{% set dataW = constant('media_subdef::TC_DATA_WIDTH') %}
|
{% set previewHtml5 = record.getSubdfefByDeviceAndMime(constant('\\databox_subdef::DEVICE_SCREEN'), ['video/ogg', 'video/mp4', 'video/webm']) %}
|
||||||
{% set dataH = constant('media_subdef::TC_DATA_HEIGHT') %}
|
{% set dataW = constant('media_subdef::TC_DATA_WIDTH') %}
|
||||||
|
{% set dataH = constant('media_subdef::TC_DATA_HEIGHT') %}
|
||||||
|
|
||||||
{% set technical_info = record.get_technical_infos %}
|
{% set technical_info = record.get_technical_infos %}
|
||||||
{% set width = technical_info[dataW].value %}
|
{% set width = technical_info[dataW].value %}
|
||||||
{% set height = technical_info[dataH].value %}
|
{% set height = technical_info[dataH].value %}
|
||||||
|
|
||||||
{% if width and height %}
|
{% if width and height %}
|
||||||
{% set rawRatio = (width / height)|number_format(3, '.') %}
|
{% set rawRatio = (width / height)|number_format(3, '.') %}
|
||||||
{% set rawRatioLength = rawRatio|length %}
|
{% set rawRatioLength = rawRatio|length %}
|
||||||
{% set ratio = rawRatio|slice(0,rawRatioLength-1) %}
|
{% set ratio = rawRatio|slice(0,rawRatioLength-1) %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% set ratio = '' %}
|
{% set ratio = '' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<video id="thumb_video" controls="" preload="auto" data-ratio="{{ ratio }}">
|
<video id="thumb_video" controls="" preload="auto" data-ratio="{{ ratio }}">
|
||||||
{% for subdef in previewHtml5 %}
|
{% for subdef in previewHtml5 %}
|
||||||
<source type="{{ subdef.get_mime() }}" src="{{ subdef.get_url() }}"/>
|
<source type="{{ subdef.get_mime() }}" src="{{ subdef.get_url() }}"/>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{{ 'No preview available' | trans }}
|
{{ 'No preview available' | trans }}
|
||||||
</video>
|
</video>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="PNB action_bar_left">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="thumb_camera_button" class="PNB">
|
|
||||||
<img src="/assets/prod/images/ThumbExtractor/camera_button.png"
|
|
||||||
alt="{{ 'take a screenshot' | trans }}"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="PNB part_title_right">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="PNB frame_canva">
|
|
||||||
<div id="thumb_delete_button">
|
|
||||||
<img src="/assets/prod/images/ThumbExtractor/delete.png"/>
|
|
||||||
</div>
|
</div>
|
||||||
<p id='thumb_info'>{{ 'To take a screenshot click on camera' | trans }}</p>
|
|
||||||
<canvas id="thumb_canvas"></canvas>
|
<div id="thumb_camera_button"></div>
|
||||||
<div id="alt_canvas_container"
|
|
||||||
style="position:absolute;overflow:hidden;top:-1200px;visibility: hidden; width:0!important;height:0!important">
|
<div class="vertical-divider"></div>
|
||||||
{% for subdef in outputFormats %}
|
|
||||||
<canvas data-width="{{ subdef.get_width() }}" data-name="{{ subdef.get_name() }}"
|
<div class="video-data-container">
|
||||||
class="alt_canvas" id="{{ subdef.get_name() }}"></canvas>
|
<dl class="dl-horizontal">
|
||||||
{% endfor %}
|
<dt>Ratio</dt>
|
||||||
|
<dd>{{ ratio }}</dd>
|
||||||
|
<dt>Type</dt>
|
||||||
|
<dd>{{ record.get_mime() }}</dd>
|
||||||
|
{% if record.exif[constant('media_subdef::TC_DATA_FRAMERATE')] is defined %}
|
||||||
|
<dt>{{ 'Images par secondes' | trans }}</dt>
|
||||||
|
<dd>{{ record.exif[constant('media_subdef::TC_DATA_FRAMERATE')] | round(2) }}ips
|
||||||
|
</dd>
|
||||||
|
{% endif %}
|
||||||
|
{% if record.exif[constant('media_subdef::TC_DATA_AUDIOCODEC')] is defined %}
|
||||||
|
<dt>{{ 'Codec Audio' | trans }}</dt>
|
||||||
|
<dd>{{ record.exif[constant('media_subdef::TC_DATA_AUDIOCODEC')] }}</dd>
|
||||||
|
{% endif %}
|
||||||
|
<dt>{{ 'Size' | trans }}</dt>
|
||||||
|
<dd>{% set width = record.exif[constant('media_subdef::TC_DATA_WIDTH')]|default
|
||||||
|
(null) %}
|
||||||
|
{% set height = record.exif[constant('media_subdef::TC_DATA_HEIGHT')]|default(null) %}
|
||||||
|
{% if width is not none and height is not none %}
|
||||||
|
{{ width ~ " x " ~ height }}
|
||||||
|
{% endif %}</dd>
|
||||||
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="thumb_slider" class="PNB">
|
<div class="horizontal-divider"></div>
|
||||||
<div id="thumb_wrapper">
|
<div id="thumbExtractor-screenshot">
|
||||||
|
<p id='thumb_info'>{{ "screenshot video" | trans }}</p>
|
||||||
|
|
||||||
|
<div id="frame">
|
||||||
|
<div class="frame_canva">
|
||||||
|
<div id="thumb_delete_button"/>
|
||||||
|
<div id="thumb_download_button"/>
|
||||||
|
<canvas id="thumb_canvas"></canvas>
|
||||||
|
<div id="alt_canvas_container"
|
||||||
|
style="position:absolute;overflow:hidden;top:-1200px;visibility: hidden; width:0!important;height:0!important">
|
||||||
|
{% for subdef in outputFormats %}
|
||||||
|
<canvas data-width="{{ subdef.get_width() }}"
|
||||||
|
data-height="{{ subdef.get_height() }}"
|
||||||
|
data-name="{{ subdef.get_name() }}"
|
||||||
|
class="alt_canvas" id="{{ subdef.get_name() }}"></canvas>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="grid">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#<div id="thumb_slider">#}
|
||||||
|
{#<div id="thumb_wrapper">#}
|
||||||
|
{#</div>#}
|
||||||
|
{#</div>#}
|
||||||
|
<div class="thumb_submit_action">
|
||||||
|
<input type="hidden" value='{{ record.get_sbas_id() }}' name='sbas_id'>
|
||||||
|
<input type="hidden" value='{{ record.get_record_id() }}' name='record_id'>
|
||||||
|
<button id="thumb_validate_button" class="btn btn-inverse"
|
||||||
|
type="button">{{ "validate" | trans }}</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="thumb_submit_action PNB">
|
|
||||||
<input type="hidden" value='{{ record.get_sbas_id() }}' name='sbas_id'>
|
|
||||||
<input type="hidden" value='{{ record.get_record_id() }}' name='record_id'>
|
|
||||||
<button id="thumb_validate_button" class="btn btn-inverse"
|
|
||||||
type="button">{{ "validate" | trans }}</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="rangeExtractor" class="">
|
<div id="rangeExtractor" class="">
|
||||||
<div class="main_title">
|
<div class="video-range-editor-side-container">
|
||||||
<img src='/assets/prod/images/ThumbExtractor/camera_title.png'/>
|
<div class="main_title">
|
||||||
{{ "video range extractor" | trans }}
|
{{ "prod:edit: chapters" | trans }}
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
</div>
|
</div>
|
||||||
<div class="video-range-editor-container"></div>
|
<div class="video-range-editor-container"></div>
|
||||||
<div class="video-data-container">
|
|
||||||
<dl class="dl-horizontal">
|
|
||||||
<dt>Ratio</dt>
|
|
||||||
<dd>{{ ratio }}</dd>
|
|
||||||
<dt>Type</dt>
|
|
||||||
<dd>{{ record.get_mime() }}</dd>
|
|
||||||
{% if record.exif[constant('media_subdef::TC_DATA_FRAMERATE')] is defined %}
|
|
||||||
<dt>{{ 'Images par secondes' | trans }}</dt>
|
|
||||||
<dd>{{ record.exif[constant('media_subdef::TC_DATA_FRAMERATE')] | round(2) }}ips
|
|
||||||
</dd>
|
|
||||||
{% endif %}
|
|
||||||
{% if record.exif[constant('media_subdef::TC_DATA_AUDIOCODEC')] is defined %}
|
|
||||||
<dt>{{ 'Codec Audio' | trans }}</dt>
|
|
||||||
<dd>{{ record.exif[constant('media_subdef::TC_DATA_AUDIOCODEC')] }}</dd>
|
|
||||||
{% endif %}
|
|
||||||
<dt>{{ 'Size' | trans }}</dt>
|
|
||||||
<dd>{% set width = record.exif[constant('media_subdef::TC_DATA_WIDTH')]|default
|
|
||||||
(null) %}
|
|
||||||
{% set height = record.exif[constant('media_subdef::TC_DATA_HEIGHT')]|default(null) %}
|
|
||||||
{% if width is not none and height is not none %}
|
|
||||||
{{ width ~ " x " ~ height }}
|
|
||||||
{% endif %}</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||