Merge pull request #2117 from lesteenman/extendedMediaFileSupport
Initial attempt at support for image and video files.
This commit is contained in:
commit
53ac7c2348
@ -430,3 +430,32 @@ tr.elected td {
|
|||||||
.motion-text.line-numbers-none .os-line-number {
|
.motion-text.line-numbers-none .os-line-number {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** Video and Image projection ***/
|
||||||
|
img.projector-image {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.projector-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 50% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-container > * {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
@ -40,6 +40,12 @@
|
|||||||
margin-top: {{scroll}}px !important;
|
margin-top: {{scroll}}px !important;
|
||||||
font-size: {{scale}}%;
|
font-size: {{scale}}%;
|
||||||
}
|
}
|
||||||
|
.mediascrollcontent {
|
||||||
|
margin-top: {{scroll/2}}em !important;
|
||||||
|
-webkit-transform: scale({{scale/100}});
|
||||||
|
-ms-transform: scale({{scale/100}});
|
||||||
|
transform: scale({{scale/100}});
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<div ng-repeat="element in elements | orderBy:'index'">
|
<div ng-repeat="element in elements | orderBy:'index'">
|
||||||
<div ng-include="element.template"></div>
|
<div ng-include="element.template"></div>
|
||||||
|
@ -38,14 +38,23 @@ angular.module('OpenSlidesApp.mediafiles', [])
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
is_presentable: ['filetype', function (filetype) {
|
is_pdf: ['filetype', function (filetype) {
|
||||||
var PRESENTABLE_FILE_TYPES = ['application/pdf'];
|
var PDF_FILE_TYPES = ['application/pdf'];
|
||||||
return _.contains(PRESENTABLE_FILE_TYPES, filetype);
|
return _.contains(PDF_FILE_TYPES, filetype);
|
||||||
}],
|
}],
|
||||||
is_image: ['filetype', function (filetype) {
|
is_image: ['filetype', function (filetype) {
|
||||||
var IMAGE_FILE_TYPES = ['image/png', 'image/jpeg', 'image/gif'];
|
var IMAGE_FILE_TYPES = ['image/png', 'image/jpeg', 'image/gif'];
|
||||||
return _.contains(IMAGE_FILE_TYPES, filetype);
|
return _.contains(IMAGE_FILE_TYPES, filetype);
|
||||||
}],
|
}],
|
||||||
|
is_video: ['filetype', function (filetype) {
|
||||||
|
var VIDEO_FILE_TYPES = [ 'video/quicktime', 'video/mp4', 'video/webm',
|
||||||
|
'video/ogg', 'video/x-flv', 'application/x-mpegURL', 'video/MP2T',
|
||||||
|
'video/3gpp', 'video/x-msvideo', 'video/x-ms-wmv', 'video/x-matroska' ];
|
||||||
|
return _.contains(VIDEO_FILE_TYPES, filetype);
|
||||||
|
}],
|
||||||
|
is_presentable: ['is_pdf', 'is_image', 'is_video', function (is_pdf, is_image, is_video) {
|
||||||
|
return is_pdf || is_image || is_video;
|
||||||
|
}],
|
||||||
mediafileUrl: [function () {
|
mediafileUrl: [function () {
|
||||||
return this.media_url_prefix + this.mediafile.name;
|
return this.media_url_prefix + this.mediafile.name;
|
||||||
}],
|
}],
|
||||||
|
@ -19,8 +19,22 @@ angular.module('OpenSlidesApp.mediafiles.projector', ['OpenSlidesApp.mediafiles'
|
|||||||
function($scope, Mediafile) {
|
function($scope, Mediafile) {
|
||||||
// load mediafile object
|
// load mediafile object
|
||||||
var mediafile = Mediafile.get($scope.element.id);
|
var mediafile = Mediafile.get($scope.element.id);
|
||||||
$scope.pdfName = mediafile.title;
|
$scope.mediafile = mediafile;
|
||||||
$scope.pdfUrl = mediafile.mediafileUrl;
|
|
||||||
|
// Allow the elements to render properly
|
||||||
|
setTimeout(function() {
|
||||||
|
if ($scope.mediafile.is_pdf) {
|
||||||
|
$scope.pdfName = mediafile.title;
|
||||||
|
$scope.pdfUrl = mediafile.mediafileUrl;
|
||||||
|
} else if ($scope.mediafile.is_video) {
|
||||||
|
var player = angular.element.find('#video-player')[0];
|
||||||
|
if ($scope.element.playing) {
|
||||||
|
player.play();
|
||||||
|
} else {
|
||||||
|
player.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp.
|
|||||||
|
|
||||||
// ** PDF presentation functions **/
|
// ** PDF presentation functions **/
|
||||||
// show document on projector
|
// show document on projector
|
||||||
$scope.showPdf = function (mediafile) {
|
$scope.showMediafile = function (mediafile) {
|
||||||
var postUrl = '/rest/core/projector/1/prune_elements/';
|
var postUrl = '/rest/core/projector/1/prune_elements/';
|
||||||
var data = [{
|
var data = [{
|
||||||
name: 'mediafiles/mediafile',
|
name: 'mediafiles/mediafile',
|
||||||
@ -147,7 +147,9 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp.
|
|||||||
page: 1,
|
page: 1,
|
||||||
scale: 'page-fit',
|
scale: 'page-fit',
|
||||||
rotate: 0,
|
rotate: 0,
|
||||||
visible: true
|
visible: true,
|
||||||
|
playing: false,
|
||||||
|
fullscreen: mediafile.is_pdf
|
||||||
}];
|
}];
|
||||||
$http.post(postUrl, data);
|
$http.post(postUrl, data);
|
||||||
};
|
};
|
||||||
@ -169,6 +171,11 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp.
|
|||||||
return Mediafile.get(presentedMediafile.id).title;
|
return Mediafile.get(presentedMediafile.id).title;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.getType = function(presentedMediafile) {
|
||||||
|
var mediafile = Mediafile.get(presentedMediafile.id);
|
||||||
|
return mediafile.is_pdf ? 'pdf' : mediafile.is_image ? 'image' : 'video';
|
||||||
|
};
|
||||||
|
|
||||||
$scope.mediafileGoToPage = function (page) {
|
$scope.mediafileGoToPage = function (page) {
|
||||||
var mediafileElement = getCurrentlyPresentedMediafile();
|
var mediafileElement = getCurrentlyPresentedMediafile();
|
||||||
if (parseInt(page) > 0) {
|
if (parseInt(page) > 0) {
|
||||||
@ -219,6 +226,26 @@ angular.module('OpenSlidesApp.mediafiles.site', ['ngFileUpload', 'OpenSlidesApp.
|
|||||||
rotate: rotation
|
rotate: rotation
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
$scope.mediafileScroll = function(scroll) {
|
||||||
|
var mediafileElement = getCurrentlyPresentedMediafile();
|
||||||
|
sendMediafileCommand({
|
||||||
|
scroll: scroll
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var setFullscreen = function(fullscreen) {
|
||||||
|
sendMediafileCommand({
|
||||||
|
fullscreen: fullscreen
|
||||||
|
});
|
||||||
|
};
|
||||||
|
$scope.mediafileToggleFullscreen = function() {
|
||||||
|
var mediafileElement = getCurrentlyPresentedMediafile();
|
||||||
|
setFullscreen(!mediafileElement.fullscreen);
|
||||||
|
};
|
||||||
|
$scope.setPlaying = function(playing) {
|
||||||
|
sendMediafileCommand({
|
||||||
|
playing: playing
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div ng-repeat="presentedMediafile in presentedMediafiles">
|
<div ng-repeat="presentedMediafile in presentedMediafiles">
|
||||||
<h3>{{ getTitle(presentedMediafile) }}</h3>
|
<h3>{{ getTitle(presentedMediafile) }}</h3>
|
||||||
<nav ng-class="getNavStyle(scroll)" class="form-inline">
|
<nav ng-show="getType(presentedMediafile) === 'pdf'" ng-class="getNavStyle(scroll)" class="form-inline">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-default" ng-click="mediafileGoToPage(presentedMediafile.page - 1)"
|
<button class="btn btn-default" ng-click="mediafileGoToPage(presentedMediafile.page - 1)"
|
||||||
ng-class="{ 'disabled': (presentedMediafile.page - 1) < 1 }"
|
ng-class="{ 'disabled': (presentedMediafile.page - 1) < 1 }"
|
||||||
@ -63,9 +63,42 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
<nav ng-show="getType(presentedMediafile) === 'image'" ng-class="getNavStyle(scroll)" class="form-inline">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-default" ng-click="mediafileToggleFullscreen()" title="{{ 'Toggle fullscreen' | translate }}"
|
||||||
|
ng-class="presentedMediafile.fullscreen ? 'btn-primary' : 'btn-default'">
|
||||||
|
<i class="fa fa-arrows-alt"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-default" ng-click="mediafileRotate()" title="{{ 'Rotate clockwise' | translate }}">
|
||||||
|
<i class="fa fa-repeat"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<nav ng-show="getType(presentedMediafile) === 'video'" ng-class="getNavStyle(scroll)" class="form-inline">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-default" ng-click="mediafileToggleFullscreen()" title="{{ 'Toggle fullscreen' | translate }}"
|
||||||
|
ng-class="presentedMediafile.fullscreen ? 'btn-primary' : 'btn-default'">
|
||||||
|
<i class="fa fa-arrows-alt"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-default" ng-click="setPlaying(false)" title="{{ 'Stop' | translate }}"
|
||||||
|
ng-class="presentedMediafile.playing ? 'btn-default' : 'btn-primary'">
|
||||||
|
<i class="fa fa-stop"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-default" ng-click="setPlaying(true)" title="{{ 'Play' | translate }}"
|
||||||
|
ng-class="presentedMediafile.playing ? 'btn-primary' : 'btn-default'">
|
||||||
|
<i class="fa fa-play"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div ng-show="!presentedMediafiles.length" class="spacer">
|
<div ng-show="!presentedMediafiles.length" class="spacer">
|
||||||
<i translate>No PDF file projected.</i>
|
<i translate>No media file projected.</i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -163,9 +196,9 @@
|
|||||||
<td ng-show="!isDeleteMode"
|
<td ng-show="!isDeleteMode"
|
||||||
os-perms="core.can_manage_projector">
|
os-perms="core.can_manage_projector">
|
||||||
<a class="btn btn-default btn-sm"
|
<a class="btn btn-default btn-sm"
|
||||||
ng-if="mediafile.mediafile.type == 'application/pdf'"
|
ng-if="mediafile.is_presentable"
|
||||||
ng-class="{ 'btn-primary': mediafile.isProjected() }"
|
ng-class="{ 'btn-primary': mediafile.isProjected() }"
|
||||||
ng-click="showPdf(mediafile)"
|
ng-click="showMediafile(mediafile)"
|
||||||
title="{{ 'Project mediafile' | translate }}">
|
title="{{ 'Project mediafile' | translate }}">
|
||||||
<i class="fa fa-video-camera"></i>
|
<i class="fa fa-video-camera"></i>
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,6 +1,18 @@
|
|||||||
<div ng-controller="SlideMediafileCtrl" class="content fullscreen">
|
<div ng-controller="SlideMediafileCtrl" class="content" ng-class="{'fullscreen': element.fullscreen, 'video-container': element.is_video}">
|
||||||
<ng-pdf template-url="/static/templates/mediafiles/slide_mediafile_partial.html"
|
<!-- PDF -->
|
||||||
ng-attr-scale="{{ element.scale }}"
|
<ng-pdf ng-if="mediafile.is_pdf" template-url="/static/templates/mediafiles/slide_mediafile_partial.html"
|
||||||
ng-attr-page="{{ element.page }}">
|
ng-attr-scale="{{ element.scale }}"
|
||||||
|
ng-attr-page="{{ element.page }}">
|
||||||
</ng-pdf>
|
</ng-pdf>
|
||||||
|
|
||||||
|
<!-- Image -->
|
||||||
|
<img ng-if="mediafile.is_image && !element.fullscreen" class='projector-image rotate{{element.rotate}}'
|
||||||
|
ng-src='{{mediafile.mediafileUrl}}'></img>
|
||||||
|
<div ng-if="mediafile.is_image && element.fullscreen" class='projector-image rotate{{element.rotate}}'
|
||||||
|
style='background-image: url("{{mediafile.mediafileUrl}}")'></div>
|
||||||
|
|
||||||
|
<!-- Video -->
|
||||||
|
<div ng-if="mediafile.is_video" class='video-container'>
|
||||||
|
<video id='video-player' ng-src="{{mediafile.mediafileUrl}}"></video>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user