diff --git a/Changelog.txt b/Changelog.txt
new file mode 100644
index 00000000..c344ae12
--- /dev/null
+++ b/Changelog.txt
@@ -0,0 +1,259 @@
+Changelog
+
+1.7.2 - (10/11/2017)
+---------------------
+- Bugfix : Fix celery
+
+
+1.7.1 - (17/10/2017)
+---------------------
+- Bugfix : Fix player size when MP3
+
+1.7.0 - (13/10/2017)
+---------------------
+- Update videojs to version 6.2.7 (and all its plugins used by Pod)
+- Update gateway part of CAS authentication
+- Update configuration for Celery (external command for encoding can be used)
+- Update auto-switch quality for video
+- Add new feature : Text overlay on video (completion page)
+- Add new feature : For videos requiring a password, now the user can send a email directly to the owner of this video instead of the Pod administrator by a form.
+- Add a configuration panel for the subtitles / legends on the video player
+- Add settings options to apply a filter on the users list in the main navigation bar
+- Add a new icon "Interactive video" on video thumbnailer when the video contains interactive parts
+- Add a button to close the info window for video(s) in iframe
+- url in the video completion page now use the highest available encoding
+- fix logger on populatedCASbackend
+- fix interactive video issue when the name of the original video is changed
+- fix interactive video height
+- fix RSS issue when empty parameter in url
+- fix elasticsearch issues for video(s) in draft mode
+- fix import in settings file
+- fix quality label when video in draft mode
+- fix slide(s) alignment with the video
+- add missings unit-test and add new ones
+
+1.6.4 - (29/06/2017)
+---------------------
+- add and fix translations
+- add score management for interactive video
+- add embed for interactive video
+- fix orderby and perpage filter
+- fix paginator and videos filter
+- update H5PP to 0.1.8 (https://github.com/DrClockwork/H5PP/releases/tag/0.1.8)
+- improve score table for interactive video
+
+1.6.3 - (14/06/2017)
+---------------------
+- update to django 1.8.18 (https://docs.djangoproject.com/en/1.11/releases/1.8.18/)
+- admin video deletion also deletes files
+- content order on same day
+- fix bug with datetime, use timezone instead
+- fix elasticsearch query when search by date
+- improve search filters
+- improve hash_id for private video
+- update h5pp to 0.1.6 (https://github.com/DrClockwork/H5PP/releases/tag/0.1.6)
+
+1.6.2 - (01/06/2017)
+---------------------
+- add private videos
+- add filter to dublincore rest
+- add proxy support for CAS authentification
+- email to user can be sent at the end of encoding
+- homepage content settings
+- remove before unload custom message
+- reordering migrations
+- fix urls file
+- fix thumbnailer settings
+- fix and improvements for rss, homepage settings and interactive video
+- improve video 360
+- general code review and pep8 format
+
+1.6.1 - (15/05/2017)
+---------------------
+- add RSS for channels
+- fix for ffmpeg overview in settings
+- fix url for h5pp
+- six version now required is 1.6.0
+- update h5pp to 0.1.55 (https://github.com/DrClockwork/H5PP/releases/tag/0.1.55)
+
+1.6.0 - (27/04/2017)
+---------------------
+- Add interactive videos (H5PP plugin)
+- Add video 360
+- Add celery
+- Update of videojs (4.12.15)
+- Add videojs panorama (0.1.1)
+- fix subtitles validation
+- fix elasticsearch when delete video
+- fix bug with search filters and count annotations
+- fix language selections
+- fix unit tests for subtitles completions
+- improve js for video completion
+- remove 'traduction' dir. Now translation are in locale dir
+- improve database request for videos research
+
+1.5.2 - (19/12/2016)
+---------------------
+- PEP8 Improvement
+- Improving headband video
+- Add FILE_UPLOAD_TEMP_DIR in settings
+- addfilter for owner on api rest
+- correct help comment
+- bugfix calendar today link
+- use owner tools in video list
+- fix icons in search results
+- clear javascript
+- tags are case and accent insensitive
+- external list of videos though iframe
+- border in video thumbs
+- layout more compact
+- new form not invalidated on creation
+- contact us sends to report adress
+
+1.5.1 - (10/11/2016)
+---------------------
+- Fix bug with start video
+- add unit test for contact us view
+- split settings in two files
+- improve management of urls
+- rename LILLE1 theme in default theme
+- add missing classes
+- fix unit test
+- add salt to protect media files
+
+1.5.0 - (26/09/2016)
+---------------------
+- fix icon/logo
+- speaker role added, list ordered according to french
+- improve french translation
+- create API rest to add user, video, chapter etc. with django-rest-framework, auth by token
+- create rest link to download all video not draft in dublin core RDF/Xml format
+- Improve channel management (many owners, add suer etc.)
+- Update django to v1.8.13
+- Update library (bootstrap, filer, formset, font awsome, etc.)
+- fix get_storage_path
+- move encoding parameter
+
+1.4.3 - (01/06/2016)
+---------------------
+- Hotfix bug with Elasticsearch
+- Fix upload limit message singular form
+- Fix unit test
+
+1.4.2 - (21/05/2016)
+---------------------
+ bugfix :
+- video template for Elasticsearch 2.X
+- acces to channel edit for channel owner
+- non working “back to previous page“ button in video add/edit.
+ feature :
+- limit daily uploads per user
+- correct singular/plural in admin filer folder title
+- allow template overriding in theme
+- alert box relies more on bootstrap native behaviors
+- add upload progress bar when adding new video file
+- video protected / authentified access separate icons
+
+1.4.1 - (17/12/2015)
+---------------------
+- fix bug in navigation.js but the function is to improve
+
+1.4.0 - (11/12/2015)
+---------------------
+- Encodage des vidéos dont la hauteur est inférieure à 240px
+- Amélioration de l'encodage des vidéos en mode portrait
+- Amélioration du moteur de recherche
+- Amélioration d'ajout d'utilisateur en ligne de commande
+- Ajout des champs langue et cursus pour une vidéo
+- Contrôle du poids des fichiers vidéos envoyés
+- Ergonomie:
+ - retrait des acces à une vidéo en mode brouillon
+ - retrait de l'onglet partage en mode brouillon
+- Enregistreurs:
+ - ajout d'une description
+ - ajout d'un icone
+ - amélioration de l'interface d'administration
+- Résolution d'un bug de nommage des vignettes (PR #60) ;
+- Finalisation des métadonnées Dublin Core dans la page de visualisation d’un contenu (PR #63) ;
+- La liste des derniers contenus ne montre plus ceux protégés par mot de passe ni ceux faisant partie de chaînes cachées (PR #69) ;
+- Un nouveau template permettant d’intégrer ou non la liste des derniers contenus dans les « flat-pages » (PR #84).
+
+1.3.6 - (27/10/2015)
+---------------------
+- hotfix in views.py : search size has to be integer
+- change default logo in player to university of Lille
+- change link to pod logo in readme
+- change thumbnail name to fix size under limit
+- bugfix with mediatype, set to video by default
+
+1.3.5 - (24/07/2015)
+---------------------
+- hotfix in chapter template : replace enrich view by chapter
+- add star for type field in enrich model
+- add width for start and end in list enrich
+
+1.3.4 - (24/07/2015)
+---------------------
+- Singular / plural forms on the video search results page, and small improvements on some texts (same one previously proposed to dev branch).
+- Fix bug in video template (meta)
+- manage bad request in video url
+
+1.3.3 - (23/07/2015)
+---------------------
+- fix bug in test for Elasticsearch url and encoding video
+- add django formset in requirement and settings (used in channel edit)
+
+1.3.2 - (23/07/2015)
+---------------------
+- fix bug in pod video admin page.
+
+1.3.1 - (22/07/2015)
+---------------------
+fix bug in video template :
+- remove share_url and build video url in template
+- fix iframe display
+
+1.3.0 - (21/07/2015)
+---------------------
+- correction several translation
+- new page contact_us with form and captcha
+- new search videos engine with template and body search
+- write up completion feature
+
+1.2 - (24/06/2015)
+---------------------
+- Add report video (in collaboration with University Le Mans)
+- Add Dublin Core tags in video template (Nice)
+- Write up enrich template
+- Write up chapter template
+- Fix bug in share video with autoplay
+- Fix bug with favicon (Nice)
+- Fix bug with contributors (Nice)
+- Massive reorganization of the theme (Nice)
+- Add import user from csv file
+
+1.1 - (02/06/2015)
+---------------------
+fusion pour version 1.0
+
+1.0.4 - (18/05/2015)
+---------------------
+- Add user root folder in session if not exist to improve folder file's listing
+- fix bug with enrichPods when saving
+- fix bug to bandwith detection function
+
+1.0.3 - (13/04/2015)
+---------------------
+- fix tags accent
+- fix live template
+- fix not auth cas
+- add new feature : mutli resolution video download
+
+1.0.2 - (23/03/2015)
+---------------------
+improve video encoding, settings and add more information in readme
+
+1.0.1 - (21/03/2015)
+---------------------
+First version on Github
+
diff --git a/pod_project/core/admin.py b/pod_project/core/admin.py
index de029c68..c1cd2ca8 100755
--- a/pod_project/core/admin.py
+++ b/pod_project/core/admin.py
@@ -19,20 +19,19 @@
avec ce programme. Si ce n'est pas le cas,
voir http://www.gnu.org/licenses/
"""
-
-from django.contrib import admin
-from django.contrib.flatpages.admin import FlatpageForm, FlatPageAdmin
-from django.contrib.flatpages.models import FlatPage
from ckeditor.widgets import CKEditorWidget
+from core.models import UserProfile, PagesMenuBas, EncodingType, ContactUs
+from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
+from django.contrib.flatpages.admin import FlatpageForm, FlatPageAdmin
+from django.contrib.flatpages.models import FlatPage
from django.utils.translation import ugettext_lazy as _
from django.utils.html import format_html
-from core.models import UserProfile, PagesMenuBas, EncodingType, ContactUs
+from modeltranslation.admin import TranslationAdmin
class PageForm(FlatpageForm):
-
class Meta:
model = FlatPage
fields = '__all__'
@@ -41,24 +40,23 @@ class Meta:
'content_en': CKEditorWidget(config_name='complete'),
}
-from modeltranslation.admin import TranslationAdmin
-
+# CustomFlatPage admin panel
class CustomFlatPageAdmin(TranslationAdmin):
list_display = ('title', 'url', )
form = PageForm
-# unregister the default FlatPage admin and register CustomFlatPageAdmin.
+# Unregister the default FlatPage admin and register CustomFlatPageAdmin.
admin.site.unregister(FlatPage)
admin.site.register(FlatPage, CustomFlatPageAdmin)
+# Basic admin panel
admin.site.register(PagesMenuBas)
# Define an inline admin descriptor for Employee model
# which acts a bit like a singleton
-
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
@@ -66,9 +64,7 @@ class UserProfileInline(admin.StackedInline):
# Define a new User admin
-
class UserAdmin(UserAdmin):
-
def clickable_email(self, obj):
email = obj.email
return format_html('{}', email, email)
@@ -86,6 +82,7 @@ def clickable_email(self, obj):
'is_staff',
'is_superuser'
)
+ ordering = ('-is_superuser', 'username', )
inlines = (UserProfileInline, )
@@ -94,12 +91,14 @@ def clickable_email(self, obj):
admin.site.register(User, UserAdmin)
+# EncodingType admin panel
class EncodingTypeAdmin(admin.ModelAdmin):
list_display = (
'name', 'bitrate_audio', 'bitrate_video', 'output_height', 'mediatype')
admin.site.register(EncodingType, EncodingTypeAdmin)
+# ContactUs admin panel
class ContactUsAdmin(admin.ModelAdmin):
list_display = ('id', 'name', 'email', 'subject', 'message')
admin.site.register(ContactUs, ContactUsAdmin)
diff --git a/pod_project/core/fixtures/initial_data.json b/pod_project/core/fixtures/initial_data.json
index adfcd907..f99d4e42 100755
--- a/pod_project/core/fixtures/initial_data.json
+++ b/pod_project/core/fixtures/initial_data.json
@@ -13,42 +13,53 @@
{
"model": "core.encodingtype",
"pk": 2,
+ "fields": {
+ "bitrate_audio": "128k",
+ "output_height": 360,
+ "name": "360",
+ "mediatype": "video",
+ "bitrate_video":"1000k"
+ }
+ },
+ {
+ "model": "core.encodingtype",
+ "pk": 3,
"fields": {
"bitrate_audio": "128k",
"output_height": 480,
"name": "480",
"mediatype": "video",
- "bitrate_video":"600k"
+ "bitrate_video": "600k"
}
},
{
"model": "core.encodingtype",
- "pk": 3,
+ "pk": 4,
"fields": {
"bitrate_audio": "196k",
"output_height": 720,
"name": "720",
"mediatype": "video",
- "bitrate_video":"1000k"
+ "bitrate_video":"2000k"
}
},
{
"model": "core.encodingtype",
- "pk": 4,
+ "pk": 5,
"fields": {
"bitrate_audio": "196k",
"output_height": 1080,
"name": "1080",
"mediatype": "video",
- "bitrate_video":"1500k"
+ "bitrate_video":"3000k"
}
},
{
"model": "core.encodingtype",
- "pk": 5,
+ "pk": 6,
"fields": {
"bitrate_audio": "128k",
- "output_height": 240,
+ "output_height": 360,
"name": "audio",
"mediatype": "audio",
"bitrate_video":""
diff --git a/pod_project/core/management/commands/check_version.py b/pod_project/core/management/commands/check_version.py
new file mode 100644
index 00000000..57a98ef6
--- /dev/null
+++ b/pod_project/core/management/commands/check_version.py
@@ -0,0 +1,18 @@
+from django.core.management.base import NoArgsCommand
+from django.conf import settings
+
+import urllib2
+import re
+
+class Command(NoArgsCommand):
+ help = 'Check the current version of Pod. Prevents if a newer version is available.'
+
+ def handle_noargs(self, **options):
+ response = urllib2.urlopen('https://github.com/EsupPortail/pod/releases/latest')
+ version = re.search('[^/]+(?=/$|$)', response.geturl())
+ if settings.VERSION != version.group():
+ print "You don't have the latest version."
+ print "Latest version : %s | Your version : %s" % (version.group(), settings.VERSION)
+ print "Link to the new version : %s" % response.geturl()
+ else:
+ print "You have the latest version : %s" % version.group()
diff --git a/pod_project/core/models.py b/pod_project/core/models.py
index 27861980..588c8808 100755
--- a/pod_project/core/models.py
+++ b/pod_project/core/models.py
@@ -255,13 +255,13 @@ class EncodingType(models.Model):
HEIGHT_CHOICES = (
(0, '0'),
(240, '240'),
+ (360, '360'),
(480, '480'),
- (640, '640'),
(720, '720'),
(1080, '1080'),
)
output_height = models.IntegerField(
- _('output_height'), choices=HEIGHT_CHOICES, default=240)
+ _('output_height'), choices=HEIGHT_CHOICES, default=360)
TYPE_CHOICES = (
("audio", 'Audio'),
("video", 'Video'),
diff --git a/pod_project/core/static/js/main.js b/pod_project/core/static/js/main.js
index b16253a1..8ebfe49f 100644
--- a/pod_project/core/static/js/main.js
+++ b/pod_project/core/static/js/main.js
@@ -286,6 +286,33 @@ $(document).on('click', 'button#button_video_report', function(event) {
return false;
});
+$(document).on('click', 'button#button_video_playlist', function(event) {
+ event.preventDefault();
+ if($(this).parent('form').length==0) {
+ alert($(this).children('span.sr-only').text());
+ } else {
+ if(expiration_date_second > 5) {
+ //show modal box with playlist selection and save/cancel buttons
+ $("#modal_playlist_form").modal({
+ show: true,
+ });
+ $('#playlist_name.list-group-item.disabled').off('click');
+ } else {
+ alert(expiredsession);
+ location.reload();
+ }
+ }
+ return false;
+});
+
+$(document).on('click', '#playlist_name', function (event) {
+ if($(this).attr('class') == 'list-group-item') {
+ $(this).attr('class', 'list-group-item active');
+ }else if($(this).attr('class') != 'list-group-item disabled') {
+ $(this).attr('class', 'list-group-item');
+ }
+});
+
/*
diff --git a/pod_project/core/static/js/player.js b/pod_project/core/static/js/player.js
index 08870f7e..ebdb1502 100644
--- a/pod_project/core/static/js/player.js
+++ b/pod_project/core/static/js/player.js
@@ -26,8 +26,6 @@ var changeRes = false;
var animation_complete = true;
var list_disp = {
'50/50': '50/50',
- '30/70': '30/70',
- '70/30': '70/30',
'100/20': 'Pip media',
'20/100': 'Pip video',
'100/0': 'only video',
@@ -35,6 +33,13 @@ var list_disp = {
};
var defaultDisp = '50/50';
var slide_height = 90; //96 en fullscreen
+var slide_color = {
+ 'document': 'yellow',
+ 'image': 'purple',
+ 'richtext': 'blue',
+ 'weblink': 'red',
+ 'embed': 'green'
+};
var videozindex = 1000;
var isPlaying = false;
var increase_view_count = false;
@@ -46,8 +51,27 @@ var previousuploaded = 0;
var mediumspeed = 0;
var intcheck = 0;
var changeResBd = false;
+var oldFormat = null; // DEPRECATED
+
/******* DOC READY ********/
$(document).ready(function() {
+ if ('MediaSource' in window) {
+ $('video').each(function() {
+ oldFormat = $(this).children('source').length > 1;
+ if (!oldFormat) {
+ $(this).children('source').remove();
+ var player = videojs(this);
+ var source = $(this).data('m3u8');
+ player.ready(function() {
+ player.src({
+ src: source,
+ type: 'application/x-mpegURL',
+ withCredentials: true
+ });
+ });
+ }
+ });
+ }
loadVideo();
// Remove right click on video
$('#player_video').bind('contextmenu', function() { return false; });
@@ -68,7 +92,6 @@ function loadVideo() {
videojs('player_video').ready(function() {
// PLAYER READY
myPlayer = this;
- myPlayer.preload("auto");
//if video 360
if(is_360) {
@@ -101,7 +124,6 @@ function loadVideo() {
myPlayer.on('loadedmetadata', loadedmetadata);
myPlayer.on('error', error); // error log for dev
myPlayer.on('durationchange', loadChapBar);
- myPlayer.on('progress', progress);
myPlayer.on('timeupdate', timeupdate);
myPlayer.on('firstplay', function(){
$.post(
@@ -131,7 +153,12 @@ function loadVideo() {
// Load plugin
// Resolution(s)
- myPlayer.videoJsResolutionSwitcher();
+ if (!oldFormat) {
+ myPlayer.videoJsQualityLevelPlayer();
+ } else {
+ myPlayer.videoJsResolutionSwitcher();
+ myPlayer.on('progress', progress);
+ }
// Display format
if ($('ul#slides li[data-type!="None"]').length > 0) {
@@ -144,16 +171,7 @@ function loadVideo() {
$('ul#slides').hide();
// Chapter(s)
- if ($('ul#chapters li').length > 0) {
- var list_chap = {};
- $('ul#chapters li').each(function () {
- list_chap[$(this).attr('data-start')] = $(this).attr('data-title');
- });
- myPlayer.videojsChapterSelector({
- list_chap : list_chap
- });
- $('ul#chapters').hide();
- }
+ myPlayer.videoJsChapters();
$('div.vjs-slide').hide();
$('div.vjs-title').hide();
@@ -177,6 +195,27 @@ function loadVideo() {
});
}
+ // Playlist
+ if ($('div.panel-playlist').length > 0) {
+ myPlayer.on('ended', function() {
+ var loop = $('.playlist_loop.active').length > 0;
+ var pos = parseInt($('.current_video').attr('id').replace(/[^\/\d]/g, ''));
+ pos = pos + 1;
+ var cell = $('#table_playlists').find('#pos_' + pos + ' a')[0];
+ if (cell != undefined) {
+ var link = cell.href;
+ if (loop) {
+ window.location = link + '&loop=true';
+ }else{
+ window.location = link;
+ }
+ } else if (loop) {
+ var link = $('#table_playlists').find('#pos_1 a')[0].href
+ window.location = link + '&loop=true';
+ }
+ });
+ };
+
myPlayer.on('resolutionchange', function() {
changeRes = true;
});
@@ -195,10 +234,11 @@ function loadVideo() {
$('.vjs-loading-spinner').css('zIndex', videozindex + 6);
$('.vjs-text-track-display').css('zIndex', videozindex + 7);
$('.vjs-overlay').css('zIndex', videozindex + 8);
- $('.vjs-control-bar').css('zIndex', videozindex + 9);
- $('.vjs-text-track-settings').css('zIndex', videozindex + 10);
+ $('.chapters-list').css('zIndex', videozindex + 9);
+ $('.vjs-control-bar').css('zIndex', videozindex + 10);
+ $('.vjs-text-track-settings').css('zIndex', videozindex + 11);
- var IS_MOBILE = /mobile|android/i.test (navigator.userAgent);
+ var IS_MOBILE = /mobile|android/i.test(navigator.userAgent);
var IS_IPHONE = (/iPhone/i).test(navigator.userAgent);
var IS_IPAD = (/iPad/i).test(navigator.userAgent);
var IS_IPOD = (/iPod/i).test(navigator.userAgent);
@@ -502,6 +542,7 @@ $(document).on(
function timeupdate(event) {
var t = myPlayer.currentTime();
+ var chapters = myPlayer.getGroupedChapters() || 0;
var all = timestamps.length;
var slide = false;
var change_slide = false;
@@ -554,6 +595,21 @@ function timeupdate(event) {
}
}
+ // Track current chapter
+ if (chapters != 0) {
+ i = 0;
+ for (i; i < chapters.id.length; i++) {
+ if (t >= chapters.start[i]) {
+ $('#'+chapters.id[i]).attr('class', 'current');
+ if (i != chapters.id.length) {
+ $('#'+chapters.id[i-1]).removeClass('current');
+ }
+ } else {
+ $('#'+chapters.id[i]).removeClass('current');
+ }
+ }
+ }
+
if (slide == true && change_slide == true ) {
isPlaying = !myPlayer.paused();
if (current_slide_type != 'None') {
@@ -632,10 +688,12 @@ function loadChapBar() {
var chapbar_left = (parseInt($(this).data('start')) / duration_vid) * 100;
var chapbar_width = ((parseInt($(this).data('end')) / duration_vid) * 100) - chapbar_left;
var data_id = $(this).data('id');
+ var data_type = $(this).data('type');
+ // Determine color
$('.vjs-chapbar-holder').append(
'
'
);
@@ -660,6 +718,7 @@ function loadChapBar() {
/**
* Calcule de manière automatique la résolution la plus optimisée pour le débit de la connexion de l'utilisateur
+ * OBSOLETE si HLS est activé
*/
function progress() {
if (typeof myPlayer.getGroupedSrc() != 'undefined' && myPlayer.getGroupedSrc().res && changeResBd == false) {
@@ -701,7 +760,6 @@ function progress() {
}
}
}
-
function error(err) {
// prints the name of the error
// alert(err.name);
@@ -710,4 +768,4 @@ function error(err) {
// this works only in some browsers
// line and stack are not supported by all vendors
console.log(err.line, err.stack);
-}
+}
\ No newline at end of file
diff --git a/pod_project/core/static/js/video-chapter-selector.js b/pod_project/core/static/js/video-chapter-selector.js
deleted file mode 100644
index efeb5b2d..00000000
--- a/pod_project/core/static/js/video-chapter-selector.js
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
-Copyright (C) 2014 Nicolas Can
-Ce programme est un logiciel libre : vous pouvez
-le redistribuer et/ou le modifier sous les termes
-de la licence GNU Public Licence telle que publiée
-par la Free Software Foundation, soit dans la
-version 3 de la licence, ou (selon votre choix)
-toute version ultérieure.
-Ce programme est distribué avec l'espoir
-qu'il sera utile, mais SANS AUCUNE
-GARANTIE : sans même les garanties
-implicites de VALEUR MARCHANDE ou
-D'APPLICABILITÉ À UN BUT PRÉCIS. Voir
-la licence GNU General Public License
-pour plus de détails.
-Vous devriez avoir reçu une copie de la licence
-GNU General Public Licence
-avec ce programme. Si ce n'est pas le cas,
-voir http://www.gnu.org/licenses/
-*/
-
-(function() {
- 'use-strict';
- var videojs = null;
- if(typeof window.videojs === 'undefined' && typeof require === 'function') {
- videojs = require('video.js');
- } else {
- videojs = window.videojs;
- }
- var list_chap = {};
- /***********************************************************************************
- * Define some helper functions
- ***********************************************************************************/
- var methods = {
- /**
- * Utility function for merging 2 objects recursively. It treats
- * arrays like plain objects and it relies on a for...in loop which will
- * break if the Object prototype is messed with.
- *
- * @param (object) destination The object to modify and return
- * @param (object) source The object to use to overwrite the first
- * object
- *
- * @returns (object) The modified first object is returned
- */
- extend : function(destination, source) {
- for (var prop in source) {
- if (typeof source[prop] == 'object' && null !== source[prop]) {
- destination[prop] = methods.extend(destination[prop] || {}, source[prop]);
- } else {
- destination[prop] = source[prop];
- }
- }
-
- return destination;
- },
-
- /**
- * In a future version, this can be made more intelligent,
- * but for now, we'll just add a "p" at the end if we are passed
- * numbers.
- *
- * @param (string) res The resolution to make a label for
- *
- * @returns (string) The label text string
- */
- chap_label : function(chap) {
- return list_chap[chap];
- }
- };
-
- /***********************************************************************************
- * Setup our chapter menu items
- ***********************************************************************************/
- (function(window, videojs) {
- var defaults = {
- list_chap: {},
- ui: true
- };
-
- /***********************************************************************************
- * Setup our chapter menu items
- ***********************************************************************************/
- var MenuItem = videojs.getComponent('MenuItem');
- var ChapterMenuItem = videojs.extend(MenuItem, {
- constructor: function(player, options) {
- // Modify options for parent MenuItem class's init.
- options.label = methods.chap_label(options.chap);
- //options.selected = (options.chap === player.getCurrentChap());
-
- // Call the parent constructor
- MenuItem.call(this, player, options);
-
- // Store the resolution as a call property
- this.chapter = options.chap;
-
- // Register our click handler
- this.on(['click', 'tap'], this.onClick);
-
- // Copy the player as a class property
- this.player = player;
- }
- });
- // Handle clicks on the menu items
- ChapterMenuItem.prototype.onClick = function() {
- this.player_.currentTime(this.chapter);
- };
- MenuItem.registerComponent('ChapterMenuItem', ChapterMenuItem);
-
- /***********************************************************************************
- * Setup our chapter menu title item
- ***********************************************************************************/
- var ChapterTitleMenuItem = videojs.extend(MenuItem, {
- constructor: function(player, options) {
- // Call the parent constructor
- MenuItem.call(this, player, options);
-
- // No click handler for the menu title
- this.off('click');
- }
- });
- MenuItem.registerComponent('ChapterTitleMenuItem', ChapterTitleMenuItem);
-
- /***********************************************************************************
- * Define our chapter selector button
- ***********************************************************************************/
- var MenuButton = videojs.getComponent('MenuButton');
- var ChapterSelectorButton = videojs.extend(MenuButton, {
- constructor: function(player, options) {
- // Copy the player as an accessible class property
- //this.player = player;
- // Add our list of available resolutions to the player object
- player.availablechap = options.available_chap;
- // Call the parent constructor
- MenuButton.call(this, player, options);
- }
- });
-
- // Set class for resolution selector button
- ChapterSelectorButton.prototype.buildCSSClass = function() {
- return MenuButton.prototype.buildCSSClass.call(this) + ' vjs-chapters-button';
- }
- //ChapterSelectorButton.prototype.className = 'vjs-chapters-button';
-
- // Create a menu item for each available chapter
- ChapterSelectorButton.prototype.createItems = function() {
- var player = this.player_,
- items = [],
- current_chap;
-
- // Add the menu title item
- items.push(new ChapterTitleMenuItem(player, {
- el: videojs.dom.createEl('li', {
- className: 'vjs-menu-title vjs-chap-menu-title',
- innerHTML: 'Chapter'
- })
- }));
-
- // Add an item for each available chapter
- for (current_chap in player.availablechap) {
- if ('length' == current_chap) {
- continue;
- }
-
- items.push(new ChapterMenuItem(player, {
- chap : player.availablechap[current_chap]
- }));
- }
-
- return items;
- };
- MenuButton.registerComponent('ChapterSelectorButton', ChapterSelectorButton);
-
- /***********************************************************************************
- * Register the plugin with videojs, main plugin function
- ***********************************************************************************/
- videojsChapterSelector = function(options) {
- // Override default options with those provided
- var settings = videojs.mergeOptions(defaults, options),
- player = this,
- available_chap = { length: 0 },
- chapterSelector;
-
- player.ready(function() {
- if (settings.list_chap != {}) {
- list_chap = settings.list_chap;
- }
-
- for (var chap in list_chap) {
- available_chap.length++;
- available_chap[chap] = chap ;
- }
-
- chapterSelector = new ChapterSelectorButton(player, {
- available_chap: available_chap
- });
-
- // Add the button to the control bar object and the DOM
- player.controlBar.videojsChapterSelector = player.controlBar.addChild(chapterSelector);
- player.controlBar.videojsChapterSelector.dispose = function() {
- this.parentNode.removeChild(this);
- }
- });
- };
-
- // Register the plugin
- videojs.registerPlugin('videojsChapterSelector', videojsChapterSelector);
- })(window, videojs);
-})();
diff --git a/pod_project/core/static/video-js/videojs-contrib-hls.min.js b/pod_project/core/static/video-js/videojs-contrib-hls.min.js
new file mode 100644
index 00000000..6791c13f
--- /dev/null
+++ b/pod_project/core/static/video-js/videojs-contrib-hls.min.js
@@ -0,0 +1,8 @@
+!function e(t,i,n){function r(s,o){if(!i[s]){if(!t[s]){var u="function"==typeof require&&require;if(!o&&u)return u(s,!0);if(a)return a(s,!0);var d=new Error("Cannot find module '"+s+"'");throw d.code="MODULE_NOT_FOUND",d}var l=i[s]={exports:{}};t[s][0].call(l.exports,function(e){var i=t[s][1][e];return r(i||e)},l,l.exports,e,t,i,n)}return i[s].exports}for(var a="function"==typeof require&&require,s=0;s=r.adStartTime&&t<=r.adEndTime)return r}return null},o=function(e,t){var i=arguments.length<=2||arguments[2]===undefined?0:arguments[2];if(e.segments)for(var r=i,o=undefined,u=0;u=32&&e<126?String.fromCharCode(e):"."},s=function(e){var t={};return Object.keys(e).forEach(function(i){var n=e[i];ArrayBuffer.isView(n)?t[i]={bytes:n.buffer,byteOffset:n.byteOffset,byteLength:n.byteLength}:t[i]=n}),t},o=function(e){var t=e.byterange||{length:Infinity,offset:0};return[t.length,t.offset,e.resolvedUri].join(",")},u={hexDump:function(e){for(var t=Array.prototype.slice.call(e),i="",n=undefined,s=undefined,o=0;o1&&this.tech_.trigger({type:"usage",name:"hls-alternate-audio"}),this.useCueTags_&&this.tech_.trigger({type:"usage",name:"hls-playlist-cue-tags"})}},{key:"setupSegmentLoaderListeners_",value:function(){var e=this;this.mainSegmentLoader_.on("bandwidthupdate",function(){var t=e.selectPlaylist(),i=e.masterPlaylistLoader_.media(),n=e.tech_.buffered(),r=n.length?n.end(n.length-1)-e.tech_.currentTime():0,a=e.bufferLowWaterLine();(!i.endList||e.duration()=a)&&e.masterPlaylistLoader_.media(t),e.tech_.trigger("bandwidthupdate")}),this.mainSegmentLoader_.on("progress",function(){e.trigger("progress")}),this.mainSegmentLoader_.on("error",function(){e.blacklistCurrentPlaylist(e.mainSegmentLoader_.error())}),this.mainSegmentLoader_.on("syncinfoupdate",function(){e.onSyncInfoUpdate_()}),this.mainSegmentLoader_.on("timestampoffset",function(){e.tech_.trigger({type:"usage",name:"hls-timestamp-offset"})}),this.audioSegmentLoader_.on("syncinfoupdate",function(){e.onSyncInfoUpdate_()}),this.mainSegmentLoader_.on("ended",function(){e.onEndOfStream()}),this.mainSegmentLoader_.on("earlyabort",function(){e.blacklistCurrentPlaylist({message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},120)}),this.mainSegmentLoader_.on("reseteverything",function(){e.tech_.trigger("hls-reset")}),this.mainSegmentLoader_.on("segmenttimemapping",function(t){e.tech_.trigger({type:"hls-segment-time-mapping",mapping:t.mapping})}),this.audioSegmentLoader_.on("ended",function(){e.onEndOfStream()})}},{key:"mediaSecondsLoaded_",value:function(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)}},{key:"load",value:function(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load()}},{key:"fastQualityChange_",value:function(){var e=this.selectPlaylist();e!==this.masterPlaylistLoader_.media()&&(this.masterPlaylistLoader_.media(e),this.mainSegmentLoader_.resetLoader())}},{key:"play",value:function(){if(!this.setupFirstPlay()){this.tech_.ended()&&this.tech_.setCurrentTime(0),this.hasPlayed_()&&this.load();var e=this.tech_.seekable();return this.tech_.duration()===Infinity&&this.tech_.currentTime()e.end(0)||e.start(0)>t.end(0)?this.seekable_=e:this.seekable_=_["default"].createTimeRanges([[t.start(0)>e.start(0)?t.start(0):e.start(0),t.end(0)0&&(i=Math.max(i,n.end(n.length-1))),t!==i&&("open"!==this.mediaSource.readyState?this.mediaSource.addEventListener("sourceopen",r):r())}},{key:"dispose",value:function(){var e=this;this.decrypter_.terminate(),this.masterPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),["AUDIO","SUBTITLES"].forEach(function(t){var i=e.mediaTypes_[t].groups;for(var n in i)i[n].forEach(function(e){e.playlistLoader&&e.playlistLoader.dispose()})}),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose()}},{key:"master",value:function(){return this.masterPlaylistLoader_.master}},{key:"media",value:function(){return this.masterPlaylistLoader_.media()||this.initialMedia_}},{key:"setupSourceBuffers_",value:function(){var e=this.masterPlaylistLoader_.media(),t=undefined;if(e&&"open"===this.mediaSource.readyState){if(t=F(this.masterPlaylistLoader_.master,e),t.length<1)return this.error="No compatible SourceBuffer configuration for the variant stream:"+e.resolvedUri,this.mediaSource.endOfStream("decode");this.mainSegmentLoader_.mimeType(t[0]),t[1]&&this.audioSegmentLoader_.mimeType(t[1]),this.excludeIncompatibleVariants_(e)}}},{key:"excludeIncompatibleVariants_",value:function(e){var t=this.masterPlaylistLoader_.master,i=2,n=null,r=undefined;e.attributes.CODECS&&(r=(0,P.parseCodecs)(e.attributes.CODECS),n=r.videoCodec,i=r.codecCount),t.playlists.forEach(function(e){var t={codecCount:2,videoCodec:null};if(e.attributes.CODECS){var r=e.attributes.CODECS;t=(0,P.parseCodecs)(r),window.MediaSource&&window.MediaSource.isTypeSupported&&!window.MediaSource.isTypeSupported('video/mp4; codecs="'+x(r)+'"')&&(e.excludeUntil=Infinity)}t.codecCount!==i&&(e.excludeUntil=Infinity),t.videoCodec!==n&&(e.excludeUntil=Infinity)})}},{key:"updateAdCues_",value:function(e){var t=0,i=this.seekable();i.length&&(t=i.start(0)),b["default"].updateAdCues(e,this.cueTagsTrack_,t)}},{key:"goalBufferLength",value:function(){var e=this.tech_.currentTime(),t=I["default"].GOAL_BUFFER_LENGTH,i=I["default"].GOAL_BUFFER_LENGTH_RATE,n=Math.max(t,I["default"].MAX_GOAL_BUFFER_LENGTH);return Math.min(t+e*i,n)}},{key:"bufferLowWaterLine",value:function(){var e=this.tech_.currentTime(),t=I["default"].BUFFER_LOW_WATER_LINE,i=I["default"].BUFFER_LOW_WATER_LINE_RATE,n=Math.max(t,I["default"].MAX_BUFFER_LOW_WATER_LINE);return Math.min(t+e*i,n)}}]),t}(_["default"].EventTarget);i.MasterPlaylistController=q}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],6:[function(e,t,i){(function(t){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(i,"__esModule",{value:!0});var r="undefined"!=typeof window?window.videojs:void 0!==t?t.videojs:null,a=n(r),s=e(9),o=n(s),u=function(){},d=function(e){var t=e["default"]?"main":"alternative";return e.characteristics&&e.characteristics.indexOf("public.accessibility.describes-video")>=0&&(t="main-desc"),t},l=function(e,t){e.abort(),e.pause(),t&&t.activePlaylistLoader&&(t.activePlaylistLoader.pause(),t.activePlaylistLoader=null)};i.stopLoaders=l;var f=function(e,t){t.activePlaylistLoader=e,e.load()};i.startLoaders=f;var c=function(e,t){return function(){var i=t.segmentLoaders,n=i[e],r=i.main,a=t.mediaTypes[e],s=a.activeTrack(),o=a.activeGroup(s),u=a.activePlaylistLoader;if(l(n,a),o){if(!o.playlistLoader)return void(u&&r.resetEverything());n.resyncLoader(),f(o.playlistLoader,a)}}};i.onGroupChanged=c;var h=function(e,t){return function(){var i=t.segmentLoaders,n=i[e],r=i.main,a=t.mediaTypes[e],s=a.activeTrack(),o=a.activeGroup(s),u=a.activePlaylistLoader;if(l(n,a),o){if(!o.playlistLoader)return void r.resetEverything();if(u===o.playlistLoader)return void f(o.playlistLoader,a);n.track&&n.track(s),n.resetEverything(),f(o.playlistLoader,a)}}};i.onTrackChanged=h;var p={AUDIO:function(e,t){return function(){var i=t.segmentLoaders[e],n=t.mediaTypes[e],r=t.blacklistCurrentPlaylist;l(i,n);var s=n.activeTrack(),o=n.activeGroup(),u=(o.filter(function(e){return e["default"]})[0]||o[0]).id,d=n.tracks[u];if(s===d)return void r({message:"Problem encountered loading the default audio track."});a["default"].log.warn("Problem encountered loading the alternate audio track.Switching back to default.");for(var f in n.tracks)n.tracks[f].enabled=n.tracks[f]===d;n.onTrackChanged()}},SUBTITLES:function(e,t){return function(){var i=t.segmentLoaders[e],n=t.mediaTypes[e];a["default"].log.warn("Problem encountered loading the subtitle track.Disabling subtitle track."),l(i,n);var r=n.activeTrack();r&&(r.mode="disabled"),n.onTrackChanged()}}};i.onError=p;var m={AUDIO:function(e,t,i){if(t){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e];t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",p[e](e,i))}},SUBTITLES:function(e,t,i){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],s=i.mediaTypes[e];t.on("loadedmetadata",function(){var e=t.media();a.playlist(e,r),a.track(s.activeTrack()),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load()}),t.on("loadedplaylist",function(){a.playlist(t.media(),r),n.paused()||a.load()}),t.on("error",p[e](e,i))}};i.setupListeners=m;var g={AUDIO:function(e,t){var i=t.mode,n=t.hls,r=t.segmentLoaders[e],s=t.requestOptions.withCredentials,u=t.master.mediaGroups,l=t.mediaTypes[e],f=l.groups,c=l.tracks;u[e]&&0!==Object.keys(u[e]).length&&"html5"===i||(u[e]={main:{"default":{"default":!0}}});for(var h in u[e]){f[h]||(f[h]=[]);for(var g in u[e][h]){var y=u[e][h][g],_=undefined;if(_=y.resolvedUri?new o["default"](y.resolvedUri,n,s):null,y=a["default"].mergeOptions({id:g,playlistLoader:_},y),m[e](e,y.playlistLoader,t),f[h].push(y),"undefined"==typeof c[g]){var v=new a["default"].AudioTrack({id:g,kind:d(y),enabled:!1,language:y.language,"default":y["default"],label:g});c[g]=v}}}r.on("error",p[e](e,t))},SUBTITLES:function(e,t){var i=t.tech,n=t.hls,r=t.segmentLoaders[e],s=t.requestOptions.withCredentials,u=t.master.mediaGroups,d=t.mediaTypes[e],l=d.groups,f=d.tracks;for(var c in u[e]){l[c]||(l[c]=[]);for(var h in u[e][c])if(!u[e][c][h].forced){var g=u[e][c][h];if(g=a["default"].mergeOptions({id:h,playlistLoader:new o["default"](g.resolvedUri,n,s)},g),m[e](e,g.playlistLoader,t),l[c].push(g),"undefined"==typeof f[h]){var y=i.addRemoteTextTrack({id:h,kind:"subtitles",enabled:!1,language:g.language,label:h},!1).track;f[h]=y}}}r.on("error",p[e](e,t))},"CLOSED-CAPTIONS":function(e,t){var i=t.tech,n=t.master.mediaGroups,r=t.mediaTypes[e],s=r.groups,o=r.tracks;for(var u in n[e]){s[u]||(s[u]=[]);for(var d in n[e][u]){var l=n[e][u][d];if(l.instreamId.match(/CC\d/)&&(s[u].push(a["default"].mergeOptions({id:d},l)),"undefined"==typeof o[d])){var f=i.addRemoteTextTrack({id:l.instreamId,kind:"captions",enabled:!1,language:l.language,label:d},!1).track;o[d]=f}}}}};i.initialize=g;var y=function(e,t){return function(i){var n=t.masterPlaylistLoader,r=t.mediaTypes[e].groups,a=n.media();if(!a)return null;var s=null;return a.attributes[e]&&(s=r[a.attributes[e]]),s=s||r.main,void 0===i?s:null===i?null:s.filter(function(e){return e.id===i.id})[0]||null}};i.activeGroup=y;var _={AUDIO:function(e,t){return function(){var i=t.mediaTypes[e].tracks;for(var n in i)if(i[n].enabled)return i[n];return null}},SUBTITLES:function(e,t){return function(){var i=t.mediaTypes[e].tracks;for(var n in i)if("showing"===i[n].mode)return i[n];return null}}};i.activeTrack=_;var v=function(e){["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(t){g[t](t,e)});var t=e.mediaTypes,i=e.masterPlaylistLoader,n=e.tech,r=e.hls;["AUDIO","SUBTITLES"].forEach(function(i){t[i].activeGroup=y(i,e),t[i].activeTrack=_[i](i,e),t[i].onGroupChanged=c(i,e),t[i].onTrackChanged=h(i,e)});var a=t.AUDIO.activeGroup(),s=(a.filter(function(e){return e["default"]})[0]||a[0]).id;t.AUDIO.tracks[s].enabled=!0,t.AUDIO.onTrackChanged(),i.on("mediachange",function(){["AUDIO","SUBTITLES"].forEach(function(e){return t[e].onGroupChanged()})});var o=function(){t.AUDIO.onTrackChanged(),n.trigger({type:"usage",name:"hls-audio-change"})};n.audioTracks().addEventListener("change",o),n.remoteTextTracks().addEventListener("change",t.SUBTITLES.onTrackChanged),r.on("dispose",function(){n.audioTracks().removeEventListener("change",o),n.remoteTextTracks().removeEventListener("change",t.SUBTITLES.onTrackChanged)}),n.clearTracks("audio");for(var u in t.AUDIO.tracks)n.audioTracks().addTrack(t.AUDIO.tracks[u])};i.setupMediaGroups=v;var b=function(){var e={};return["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach(function(t){e[t]={groups:{},tracks:{},activePlaylistLoader:null,activeGroup:u,activeTrack:u,onGroupChanged:u,onTrackChanged:u}}),e};i.createMediaTypes=b}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],7:[function(e,t,i){(function(t){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var n="undefined"!=typeof window?window.videojs:void 0!==t?t.videojs:null,r=function(e){return e&&e.__esModule?e:{"default":e}}(n),a=e(2),s={FAILURE:2,TIMEOUT:-101,ABORTED:-102};i.REQUEST_ERRORS=s;var o=function(e){var t=(undefined,undefined);return t=e.offset+e.length-1,"bytes="+e.offset+"-"+t},u=function(e){var t={};return e.byterange&&(t.Range=o(e.byterange)),t},d=function(e){e.forEach(function(e){e.abort()})},l=function(e){return{bandwidth:e.bandwidth,bytesReceived:e.bytesReceived||0,roundTripTime:e.roundTripTime||0}},f=function(e){var t=e.target,i=Date.now()-t.requestTime,n={bandwidth:Infinity,bytesReceived:0,roundTripTime:i||0};return n.bytesReceived=e.loaded,n.bandwidth=Math.floor(n.bytesReceived/n.roundTripTime*8*1e3),n},c=function(e,t){return t.timedout?{status:t.status,message:"HLS request timed-out at URL: "+t.uri,code:s.TIMEOUT,xhr:t}:t.aborted?{status:t.status,message:"HLS request aborted at URL: "+t.uri,code:s.ABORTED,xhr:t}:e?{status:t.status,message:"HLS request errored at URL: "+t.uri,code:s.FAILURE,xhr:t}:null},h=function(e,t){return function(i,n){var r=n.response,a=c(i,n);if(a)return t(a,e);if(16!==r.byteLength)return t({status:n.status,message:"Invalid HLS key at URL: "+n.uri,code:s.FAILURE,xhr:n},e);var o=new DataView(r);return e.key.bytes=new Uint32Array([o.getUint32(0),o.getUint32(4),o.getUint32(8),o.getUint32(12)]),t(null,e)}},p=function(e,t){return function(i,n){var r=n.response,a=c(i,n);return a?t(a,e):0===r.byteLength?t({status:n.status,message:"Empty HLS segment content at URL: "+n.uri,code:s.FAILURE,xhr:n},e):(e.map.bytes=new Uint8Array(n.response),t(null,e))}},m=function(e,t){return function(i,n){var r=n.response,a=c(i,n);return a?t(a,e):0===r.byteLength?t({status:n.status,message:"Empty HLS segment content at URL: "+n.uri,code:s.FAILURE,xhr:n},e):(e.stats=l(n),e.key?e.encryptedBytes=new Uint8Array(n.response):e.bytes=new Uint8Array(n.response),t(null,e))}},g=function(e,t,i){var n=function r(n){if(n.data.source===t.requestId){e.removeEventListener("message",r);var a=n.data.decrypted;return t.bytes=new Uint8Array(a.bytes,a.byteOffset,a.byteLength),i(null,t)}};e.addEventListener("message",n),e.postMessage((0,a.createTransferableMessage)({source:t.requestId,encrypted:t.encryptedBytes,key:t.key.bytes,iv:t.key.iv}),[t.encryptedBytes.buffer,t.key.bytes.buffer])},y=function(e){return e.reduce(function(e,t){return t.code>e.code?t:e})},_=function(e,t,i){var n=[],r=0;return function(a,s){if(a&&(d(e),n.push(a)),(r+=1)===e.length){if(s.endOfAllRequests=Date.now(),n.length>0){var o=y(n);return i(o,s)}return s.encryptedBytes?g(t,s,i):i(null,s)}}},v=function(e,t){return function(i){return e.stats=r["default"].mergeOptions(e.stats,f(i)),!e.stats.firstBytesReceivedAt&&e.stats.bytesReceived&&(e.stats.firstBytesReceivedAt=Date.now()),t(i,e)}},b=function(e,t,i,n,a,s){var o=[],l=_(o,i,s);if(n.key){var f=r["default"].mergeOptions(t,{uri:n.key.resolvedUri,responseType:"arraybuffer"}),c=h(n,l),g=e(f,c);o.push(g)}if(n.map&&!n.map.bytes){var y=r["default"].mergeOptions(t,{uri:n.map.resolvedUri,responseType:"arraybuffer",headers:u(n.map)}),b=p(n,l),T=e(y,b);o.push(T)}var S=r["default"].mergeOptions(t,{uri:n.resolvedUri,responseType:"arraybuffer",headers:u(n)}),w=m(n,l),k=e(S,w);return k.addEventListener("progress",v(n,a)),o.push(k),function(){return d(o)}};i.mediaSegmentRequest=b}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],8:[function(e,t,i){(function(n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0});var s=function(){function e(e,t){for(var i=0;i")),this.logger_("initialize");var n=function(){return i.monitorCurrentTime_()},r=function(){return i.techWaiting_()},s=function(){return i.cancelTimer_()},o=function(){return i.fixesBadSeeks_()};this.tech_.on("seekablechanged",o),this.tech_.on("waiting",r),this.tech_.on(h,s),this.tech_.on("canplay",n),this.dispose=function(){i.logger_("dispose"),i.tech_.off("seekablechanged",o),i.tech_.off("waiting",r),i.tech_.off(h,s),i.tech_.off("canplay",n),i.checkCurrentTimeTimeout_&&u["default"].clearTimeout(i.checkCurrentTimeTimeout_),i.cancelTimer_()}}return s(e,[{key:"monitorCurrentTime_",value:function(){this.checkCurrentTime_(),this.checkCurrentTimeTimeout_&&u["default"].clearTimeout(this.checkCurrentTimeTimeout_),this.checkCurrentTimeTimeout_=u["default"].setTimeout(this.monitorCurrentTime_.bind(this),250)}},{key:"checkCurrentTime_",value:function(){if(this.tech_.seeking()&&this.fixesBadSeeks_())return this.consecutiveUpdates=0,void(this.lastRecordedTime=this.tech_.currentTime());if(!this.tech_.paused()&&!this.tech_.seeking()){var e=this.tech_.currentTime(),t=this.tech_.buffered();if(this.lastRecordedTime===e&&(!t.length||e+l["default"].SAFE_TIME_DELTA>=t.end(t.length-1)))return this.techWaiting_();this.consecutiveUpdates>=5&&e===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):e===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=e)}}},{key:"cancelTimer_",value:function(){this.consecutiveUpdates=0,this.timer_&&(this.logger_("cancelTimer_"),clearTimeout(this.timer_)),this.timer_=null}},{key:"fixesBadSeeks_",value:function(){var e=this.tech_.seeking(),t=this.seekable(),i=this.tech_.currentTime(),n=undefined;if(e&&this.afterSeekableWindow_(t,i)){n=t.end(t.length-1)}if(e&&this.beforeSeekableWindow_(t,i)){n=t.start(0)+l["default"].SAFE_TIME_DELTA}return void 0!==n&&(this.logger_("Trying to seek outside of seekable at time "+i+" with seekable range "+l["default"].printableRange(t)+". Seeking to "+n+"."),this.tech_.setCurrentTime(n),!0)}},{key:"waiting_",value:function(){if(!this.techWaiting_()){var e=this.tech_.currentTime(),t=this.tech_.buffered(),i=l["default"].findRange(t,e);return i.length&&e+3<=i.end(0)?(this.cancelTimer_(),this.tech_.setCurrentTime(e),this.logger_("Stopped at "+e+" while inside a buffered region ["+i.start(0)+" -> "+i.end(0)+"]. Attempting to resume playback by seeking to the current time."),void this.tech_.trigger({type:"usage",name:"hls-unknown-waiting"})):void 0}}},{key:"techWaiting_",value:function(){var e=this.seekable(),t=this.tech_.currentTime();if(this.tech_.seeking()&&this.fixesBadSeeks_())return!0;if(this.tech_.seeking()||null!==this.timer_)return!0;if(this.beforeSeekableWindow_(e,t)){var i=e.end(e.length-1);return this.logger_("Fell out of live window at time "+t+". Seeking to live point (seekable end) "+i),this.cancelTimer_(),this.tech_.setCurrentTime(i),this.tech_.trigger({type:"usage",name:"hls-live-resync"}),!0}var n=this.tech_.buffered(),r=l["default"].findNextRange(n,t);if(this.videoUnderflow_(r,n,t))return this.cancelTimer_(),this.tech_.setCurrentTime(t),this.tech_.trigger({type:"usage",name:"hls-video-underflow"}),!0;if(r.length>0){var a=r.start(0)-t;return this.logger_("Stopped at "+t+", setting timer for "+a+", seeking to "+r.start(0)),this.timer_=setTimeout(this.skipTheGap_.bind(this),1e3*a,t),!0}return!1}},{key:"afterSeekableWindow_",value:function(e,t){return!!e.length&&t>e.end(e.length-1)+l["default"].SAFE_TIME_DELTA}},{key:"beforeSeekableWindow_",value:function(e,t){return!!(e.length&&e.start(0)>0&&t2)return{start:r,end:a}}return null}},{key:"logger_",value:function(){}}]),e}();i["default"]=p,t.exports=i["default"]}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],9:[function(e,t,i){(function(t){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(i,"__esModule",{value:!0});var s=function(){function e(e,t){for(var i=0;i=500?4:2},this.trigger("error")}},{key:"haveMetadata",value:function(e,t){var i=this;this.request=null,this.state="HAVE_METADATA";var n=new c["default"].Parser;n.push(e.responseText),n.end(),n.manifest.uri=t,n.manifest.attributes=n.manifest.attributes||{};var r=y(this.master,n.manifest);this.targetDuration=n.manifest.targetDuration,r?(this.master=r,this.media_=this.master.playlists[n.manifest.uri]):this.trigger("playlistunchanged"),this.media().endList||(p["default"].clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=p["default"].setTimeout(function(){i.trigger("mediaupdatetimeout")},b(this.media(),!!r))),this.trigger("loadedplaylist")}},{key:"dispose",value:function(){this.stopRequest(),p["default"].clearTimeout(this.mediaUpdateTimeout)}},{key:"stopRequest",value:function(){if(this.request){var e=this.request;this.request=null,e.onreadystatechange=null,e.abort()}}},{key:"media",value:function(e){var t=this;if(!e)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);var i=this.state;if("string"==typeof e){if(!this.master.playlists[e])throw new Error("Unknown playlist URI: "+e);e=this.master.playlists[e]}var n=!this.media_||e.uri!==this.media_.uri;if(this.master.playlists[e.uri].endList)return this.request&&(this.request.onreadystatechange=null,this.request.abort(),this.request=null),this.state="HAVE_METADATA",this.media_=e,void(n&&(this.trigger("mediachanging"),this.trigger("mediachange")));if(n){if(this.state="SWITCHING_MEDIA",this.request){if((0,d["default"])(this.master.uri,e.uri)===this.request.url)return;this.request.onreadystatechange=null,this.request.abort(),this.request=null}this.media_&&this.trigger("mediachanging"),this.request=this.hls_.xhr({uri:(0,d["default"])(this.master.uri,e.uri),withCredentials:this.withCredentials},function(n,r){if(t.request){if(n)return t.playlistRequestError(t.request,e.uri,i);t.haveMetadata(r,e.uri),"HAVE_MASTER"===i?t.trigger("loadedmetadata"):t.trigger("mediachange")}})}}},{key:"pause",value:function(){this.stopRequest(),p["default"].clearTimeout(this.mediaUpdateTimeout),"HAVE_NOTHING"===this.state&&(this.started=!1),"SWITCHING_MEDIA"===this.state?this.media_?this.state="HAVE_METADATA":this.state="HAVE_MASTER":"HAVE_CURRENT_METADATA"===this.state&&(this.state="HAVE_METADATA")}},{key:"load",value:function(e){var t=this;p["default"].clearTimeout(this.mediaUpdateTimeout);var i=this.media();if(e){var n=i?i.targetDuration/2*1e3:5e3;return void(this.mediaUpdateTimeout=p["default"].setTimeout(function(){return t.load()},n))}if(!this.started)return void this.start();i&&!i.endList?this.trigger("mediaupdatetimeout"):this.trigger("loadedplaylist")}},{key:"start",value:function(){var e=this;this.started=!0,this.request=this.hls_.xhr({uri:this.srcUrl,withCredentials:this.withCredentials},function(t,i){if(e.request){if(e.request=null,t)return e.error={status:i.status,message:"HLS playlist request error at URL: "+e.srcUrl,responseText:i.responseText,code:2},"HAVE_NOTHING"===e.state&&(e.started=!1),e.trigger("error");var n=new c["default"].Parser;return n.push(i.responseText),(n.end(),e.state="HAVE_MASTER",n.manifest.uri=e.srcUrl,n.manifest.playlists)?(e.master=n.manifest,_(e.master),v(e.master),e.trigger("loadedplaylist"),void(e.request||e.media(n.manifest.playlists[0]))):(e.master={mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:p["default"].location.href,playlists:[{uri:e.srcUrl}]},e.master.playlists[e.srcUrl]=e.master.playlists[0],e.master.playlists[0].resolvedUri=e.srcUrl,e.master.playlists[0].attributes=e.master.playlists[0].attributes||{},e.haveMetadata(i,e.srcUrl),e.trigger("loadedmetadata"))}})}}]),t}(l.EventTarget);i["default"]=T}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],10:[function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(i,"__esModule",{value:!0});var r=e(3),a=n(r),s=e(11),o=n(s),u=e(19),d=function(e,t){var i=undefined;return e?(i=window.getComputedStyle(e),i?i[t]:""):""},l=function(e,t){var i=e.slice();e.sort(function(e,n){var r=t(e,n);return 0===r?i.indexOf(e)-i.indexOf(n):r})},f=function(e,t){var i=undefined,n=undefined;return e.attributes.BANDWIDTH&&(i=e.attributes.BANDWIDTH),i=i||window.Number.MAX_VALUE,t.attributes.BANDWIDTH&&(n=t.attributes.BANDWIDTH),n=n||window.Number.MAX_VALUE,i-n};i.comparePlaylistBandwidth=f;var c=function(e,t){var i=undefined,n=undefined;return e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width&&(i=e.attributes.RESOLUTION.width),i=i||window.Number.MAX_VALUE,t.attributes.RESOLUTION&&t.attributes.RESOLUTION.width&&(n=t.attributes.RESOLUTION.width),n=n||window.Number.MAX_VALUE,i===n&&e.attributes.BANDWIDTH&&t.attributes.BANDWIDTH?e.attributes.BANDWIDTH-t.attributes.BANDWIDTH:i-n};i.comparePlaylistResolution=c;var h=function(e,t,i,n){var r=e.playlists.map(function(e){var t=undefined,i=undefined,n=undefined;return t=e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width,i=e.attributes.RESOLUTION&&e.attributes.RESOLUTION.height,n=e.attributes.BANDWIDTH,n=n||window.Number.MAX_VALUE,{bandwidth:n,width:t,height:i,playlist:e}});l(r,function(e,t){return e.bandwidth-t.bandwidth}),r=r.filter(function(e){return!o["default"].isIncompatible(e.playlist)});var s=r.filter(function(e){return o["default"].isEnabled(e.playlist)});s.length||(s=r.filter(function(e){return!o["default"].isDisabled(e.playlist)}));var u=s.filter(function(e){return e.bandwidth*a["default"].BANDWIDTH_VARIANCEi||e.height>n}),g=m.filter(function(e){return e.width===m[0].width&&e.height===m[0].height}),d=g[g.length-1],y=g.filter(function(e){return e.bandwidth===d.bandwidth})[0]);var _=y||p||f||s[0]||r[0];return _?_.playlist:null};i.simpleSelector=h;var p=function(){return h(this.playlists.master,this.systemBandwidth,parseInt(d(this.tech_.el(),"width"),10),parseInt(d(this.tech_.el(),"height"),10))};i.lastBandwidthSelector=p;var m=function(e){var t=-1;if(e<0||e>1)throw new Error("Moving average bandwidth decay must be between 0 and 1.");return function(){return t<0&&(t=this.systemBandwidth),t=e*this.systemBandwidth+(1-e)*t,h(this.playlists.master,t,parseInt(d(this.tech_.el(),"width"),10),parseInt(d(this.tech_.el(),"height"),10))}};i.movingAverageBandwidthSelector=m;var g=function(e){var t=e.master,i=e.currentTime,n=e.bandwidth,r=e.duration,a=e.segmentDuration,s=e.timeUntilRebuffer,u=e.currentTimeline,d=e.syncController,c=t.playlists.filter(function(e){return!o["default"].isIncompatible(e)}),h=c.filter(o["default"].isEnabled);h.length||(h=c.filter(function(e){return!o["default"].isDisabled(e)}));var p=h.filter(o["default"].hasAttribute.bind(null,"BANDWIDTH")),m=p.map(function(e){var t=d.getSyncPoint(e,r,u,i),l=t?1:2;return{playlist:e,rebufferingImpact:o["default"].estimateSegmentRequestTime(a,n,e)*l-s}}),g=m.filter(function(e){return e.rebufferingImpact<=0});return l(g,function(e,t){return f(t.playlist,e.playlist)}),g.length?g[0]:(l(m,function(e,t){return e.rebufferingImpact-t.rebufferingImpact}),m[0]||null)};i.minRebufferMaxBandwidthSelector=g;var y=function(){var e=this.playlists.master.playlists.filter(o["default"].isEnabled);return l(e,function(e,t){return f(e,t)}),e.filter(function(e){return(0,u.parseCodecs)(e.attributes.CODECS).videoCodec})[0]||null};i.lowestBitrateCompatibleVariantSelector=y},{}],11:[function(e,t,i){(function(t){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var n="undefined"!=typeof window?window.videojs:void 0!==t?t.videojs:null,r=e(32),a=function(e){return e&&e.__esModule?e:{"default":e}}(r),s=function(e,t){var i=0,n=t-e.mediaSequence,r=e.segments[n];if(r){if("undefined"!=typeof r.start)return{result:r.start,precise:!0};if("undefined"!=typeof r.end)return{result:r.end-r.duration,precise:!0}}for(;n--;){if(r=e.segments[n],"undefined"!=typeof r.end)return{result:i+r.end,precise:!0};if(i+=r.duration,"undefined"!=typeof r.start)return{result:i+r.start,precise:!0}}return{result:i,precise:!1}},o=function(e,t){for(var i=0,n=undefined,r=t-e.mediaSequence;ri){var r=[i,t];t=r[0],i=r[1]}if(t<0){for(var a=t;a=n););return Math.max(0,t)};i.safeLiveIndex=f;var c=function(e,t,i){if(!e||!e.segments)return null;if(e.endList)return d(e);if(null===t)return null;t=t||0;var n=i?f(e):e.segments.length;return u(e,e.mediaSequence+n,t)};i.playlistEnd=c;var h=function(e,t){var i=t||0,r=c(e,t,!0);return null===r?(0,n.createTimeRange)():(0,n.createTimeRange)(i,r)};i.seekable=h;var p=function(e){return e-Math.floor(e)==0},m=function(e,t){if(p(t))return t+.1*e;for(var i=t.toString().split(".")[1].length,n=1;n<=i;n++){var r=Math.pow(10,n),a=t*r;if(p(a)||n===i)return(a+e)/r}},g=m.bind(null,1),y=m.bind(null,-1),_=function(e,t,i,n){var r=undefined,a=undefined,s=e.segments.length,o=t-n;if(o<0){if(i>0)for(r=i-1;r>=0;r--)if(a=e.segments[r],(o+=y(a.duration))>0)return{mediaIndex:r,startTime:n-l(e,i,r)};return{mediaIndex:0,startTime:t}}if(i<0){for(r=i;r<0;r++)if((o-=e.targetDuration)<0)return{mediaIndex:0,startTime:t};i=0}for(r=i;rDate.now()};i.isBlacklisted=v;var b=function(e){return e.excludeUntil&&e.excludeUntil===Infinity};i.isIncompatible=b;var T=function(e){var t=v(e);return!e.disabled&&!t};i.isEnabled=T;var S=function(e){return e.disabled};i.isDisabled=S;var w=function(e){for(var t=0;t=t})},d=function(e,t){return o(e,function(e){return e-1/30>=t})},l=function(e){if(e.length<2)return a["default"].createTimeRanges();for(var t=[],i=1;i=r};if(e)for(i=0;i "+e.end(i));return t.join(", ")},g=function(e,t){var i=arguments.length<=2||arguments[2]===undefined?1:arguments[2];return((e.length?e.end(e.length-1):0)-t)/i};i["default"]={findRange:u,findNextRange:d,findGaps:l,findSoleUncommonTimeRangesEnd:f,getSegmentBufferedPercent:p,TIME_FUDGE_FACTOR:1/30,SAFE_TIME_DELTA:.1,printableRange:m,timeUntilRebuffer:g},t.exports=i["default"]}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],13:[function(e,t,i){(function(e){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var n="undefined"!=typeof window?window.videojs:void 0!==e?e.videojs:null,r=function(e){return e&&e.__esModule?e:{"default":e}}(n),a={errorInterval:30,getSource:function(e){return e(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_)}},s=function u(e,t){var i=0,n=0,s=r["default"].mergeOptions(a,t);e.ready(function(){e.trigger({type:"usage",name:"hls-error-reload-initialized"})});var o=function(){n&&e.currentTime(n)},d=function(t){null!==t&&t!==undefined&&(n=e.duration()!==Infinity&&e.currentTime()||0,e.one("loadedmetadata",o),e.src(t),e.trigger({type:"usage",name:"hls-error-reload"}),e.play())},l=function(){return Date.now()-i<1e3*s.errorInterval?void e.trigger({type:"usage",name:"hls-error-reload-canceled"}):s.getSource&&"function"==typeof s.getSource?(i=Date.now(),s.getSource.call(e,d)):void r["default"].log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")},f=function h(){e.off("loadedmetadata",o),e.off("error",l),e.off("dispose",h)},c=function(t){f(),u(e,t)};e.on("error",l),e.on("dispose",f),e.reloadSourceOnError=c},o=function(e){s(this,e)};i["default"]=o,t.exports=i["default"]}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],14:[function(e,t,i){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0});var r=e(11),a=function(e,t,i){return function(n){var a=e.master.playlists[t],s=(0,r.isIncompatible)(a),o=(0,r.isEnabled)(a);return void 0===n?o:(n?delete a.disabled:a.disabled=!0,n===o||s||(i(),n?e.trigger("renditionenabled"):e.trigger("renditiondisabled")),n)}},s=function u(e,t,i){n(this,u);var r=e.masterPlaylistController_.fastQualityChange_.bind(e.masterPlaylistController_);if(t.attributes.RESOLUTION){var s=t.attributes.RESOLUTION;this.width=s.width,this.height=s.height}this.bandwidth=t.attributes.BANDWIDTH,this.id=i,this.enabled=a(e.playlists,t.uri,r)},o=function(e){var t=e.playlists;e.representations=function(){return t.master.playlists.filter(function(e){return!(0,r.isIncompatible)(e)}).map(function(t,i){return new s(e,t,t.uri)})}};i["default"]=o,t.exports=i["default"]},{}],15:[function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(i,"__esModule",{value:!0});var r=e(63),a=n(r),s=e(32),o=n(s),u=function(e,t){return/^[a-z]+:/i.test(t)?t:(/\/\//i.test(e)||(e=a["default"].buildAbsoluteURL(o["default"].location.href,e)),a["default"].buildAbsoluteURL(e,t))};i["default"]=u,t.exports=i["default"]},{}],16:[function(e,t,i){(function(t){"use strict";function n(e){return e&&e.__esModule?e:{"default":e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(i,"__esModule",{value:!0});var s=function(){function e(e,t){for(var i=0;i0&&e.start(0)"))}return a(t,e),s(t,[{key:"resetStats_",value:function(){this.mediaBytesTransferred=0,this.mediaRequests=0,this.mediaRequestsAborted=0,this.mediaRequestsTimedout=0,this.mediaRequestsErrored=0,this.mediaTransferDuration=0,this.mediaSecondsLoaded=0}},{key:"dispose",value:function(){this.state="DISPOSED",this.pause(),this.abort_(),this.sourceUpdater_&&this.sourceUpdater_.dispose(),this.resetStats_()}},{key:"abort",value:function(){if("WAITING"!==this.state)return void(this.pendingSegment_&&(this.pendingSegment_=null));this.abort_(),this.state="READY",this.paused()||this.monitorBuffer_()}},{key:"abort_",value:function(){this.pendingSegment_&&this.pendingSegment_.abortRequests(),this.pendingSegment_=null}},{key:"error",value:function(e){return void 0!==e&&(this.error_=e),this.pendingSegment_=null,this.error_}},{key:"endOfStream",value:function(){this.ended_=!0,this.pause(),this.trigger("ended")}},{key:"buffered_",value:function(){return this.sourceUpdater_?this.sourceUpdater_.buffered():f["default"].createTimeRanges()}},{key:"initSegment",value:function(e){var t=!(arguments.length<=1||arguments[1]===undefined)&&arguments[1];if(!e)return null;var i=(0,b.initSegmentId)(e),n=this.initSegments_[i];return t&&!n&&e.bytes&&(this.initSegments_[i]=n={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:e.bytes}),n||e}},{key:"couldBeginLoading_",value:function(){return this.playlist_&&(this.sourceUpdater_||this.mimeType_&&"INIT"===this.state)&&!this.paused()}},{key:"load",value:function(){if(this.monitorBuffer_(),this.playlist_){if(this.syncController_.setDateTimeMapping(this.playlist_),"INIT"===this.state&&this.couldBeginLoading_())return this.init_()
+;!this.couldBeginLoading_()||"READY"!==this.state&&"INIT"!==this.state||(this.state="READY")}}},{key:"init_",value:function(){return this.state="READY",this.sourceUpdater_=new h["default"](this.mediaSource_,this.mimeType_),this.resetEverything(),this.monitorBuffer_()}},{key:"playlist",value:function(e){var t=arguments.length<=1||arguments[1]===undefined?{}:arguments[1];if(e){var i=this.playlist_,n=this.pendingSegment_;if(this.playlist_=e,this.xhrOptions_=t,this.hasPlayed_()||(e.syncInfo={mediaSequence:e.mediaSequence,time:0}),this.trigger("syncinfoupdate"),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();if(!i||i.uri!==e.uri)return void(null!==this.mediaIndex&&this.resyncLoader());var r=e.mediaSequence-i.mediaSequence;this.logger_("mediaSequenceDiff",r),null!==this.mediaIndex&&(this.mediaIndex-=r),n&&(n.mediaIndex-=r,n.mediaIndex>=0&&(n.segment=e.segments[n.mediaIndex])),this.syncController_.saveExpiredSegmentInfo(i,e)}}},{key:"pause",value:function(){this.checkBufferTimeout_&&(y["default"].clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=null)}},{key:"paused",value:function(){return null===this.checkBufferTimeout_}},{key:"mimeType",value:function(e){this.mimeType_||(this.mimeType_=e,"INIT"===this.state&&this.couldBeginLoading_()&&this.init_())}},{key:"resetEverything",value:function(){this.ended_=!1,this.resetLoader(),this.remove(0,this.duration_()),this.trigger("reseteverything")}},{key:"resetLoader",value:function(){this.fetchAtBuffer_=!1,this.resyncLoader()}},{key:"resyncLoader",value:function(){this.mediaIndex=null,this.syncPoint_=null,this.abort()}},{key:"remove",value:function(e,t){this.sourceUpdater_&&this.sourceUpdater_.remove(e,t),(0,v["default"])(e,t,this.segmentMetadataTrack_)}},{key:"monitorBuffer_",value:function(){this.checkBufferTimeout_&&y["default"].clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=y["default"].setTimeout(this.monitorBufferTick_.bind(this),1)}},{key:"monitorBufferTick_",value:function(){"READY"===this.state&&this.fillBuffer_(),this.checkBufferTimeout_&&y["default"].clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=y["default"].setTimeout(this.monitorBufferTick_.bind(this),500)}},{key:"fillBuffer_",value:function(){if(!this.sourceUpdater_.updating()){this.syncPoint_||(this.syncPoint_=this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_()));var e=this.checkBuffer_(this.buffered_(),this.playlist_,this.mediaIndex,this.hasPlayed_(),this.currentTime_(),this.syncPoint_);if(e){if(k(this.playlist_,this.mediaSource_,e.mediaIndex))return void this.endOfStream();(e.mediaIndex!==this.playlist_.segments.length-1||"ended"!==this.mediaSource_.readyState||this.seeking_())&&((e.timeline!==this.currentTimeline_||null!==e.startOfSegment&&e.startOfSegment=this.goalBufferLength_())return null;if(!n&&u>=1)return null;if(this.logger_("checkBuffer_","mediaIndex:",i,"hasPlayed:",n,"currentTime:",r,"syncPoint:",a,"fetchAtBuffer:",this.fetchAtBuffer_,"bufferedTime:",u),null===a)return i=this.getSyncSegmentCandidate_(t),this.logger_("getSync","mediaIndex:",i),this.generateSegmentInfo_(t,i,null,!0);if(null!==i){this.logger_("walkForward","mediaIndex:",i+1);var l=t.segments[i];return o=l&&l.end?l.end:s,this.generateSegmentInfo_(t,i+1,o,!1)}if(this.fetchAtBuffer_){var f=d["default"].getMediaInfoForTime(t,s,a.segmentIndex,a.time);i=f.mediaIndex,o=f.startTime}else{var f=d["default"].getMediaInfoForTime(t,r,a.segmentIndex,a.time);i=f.mediaIndex,o=f.startTime}return this.logger_("getMediaIndexForTime","mediaIndex:",i,"startOfSegment:",o),this.generateSegmentInfo_(t,i,o,!1)}},{key:"getSyncSegmentCandidate_",value:function(e){var t=this;if(-1===this.currentTimeline_)return 0;var i=e.segments.map(function(e,t){return{timeline:e.timeline,segmentIndex:t}}).filter(function(e){return e.timeline===t.currentTimeline_});return i.length?i[Math.min(i.length-1,1)].segmentIndex:Math.max(e.segments.length-1,0)}},{key:"generateSegmentInfo_",value:function(e,t,i,n){if(t<0||t>=e.segments.length)return null;var r=e.segments[t];return{requestId:"segment-loader-"+Math.random(),uri:r.resolvedUri,mediaIndex:t,isSyncRequest:n,startOfSegment:i,playlist:e,bytes:null,encryptedBytes:null,timestampOffset:null,timeline:r.timeline,duration:r.duration,segment:r}}},{key:"abortRequestEarly_",value:function(e){if(this.hls_.tech_.paused()||!this.xhrOptions_.timeout||!this.playlist_.attributes.BANDWIDTH)return!1;if(Date.now()-(e.firstBytesReceivedAt||Date.now())<1e3)return!1;var t=this.currentTime_(),i=e.bandwidth,n=this.pendingSegment_.duration,r=d["default"].estimateSegmentRequestTime(n,i,this.playlist_,e.bytesReceived),a=(0,S.timeUntilRebuffer)(this.buffered_(),t,this.hls_.tech_.playbackRate())-1;if(r<=a)return!1;var s=(0,w.minRebufferMaxBandwidthSelector)({master:this.hls_.playlists.master,currentTime:t,bandwidth:i,duration:this.duration_(),segmentDuration:n,timeUntilRebuffer:a,currentTimeline:this.currentTimeline_,syncController:this.syncController_});if(s){var o=r-a,u=o-s.rebufferingImpact,l=.5;return a<=S.TIME_FUDGE_FACTOR&&(l=1),!s.playlist||s.playlist.uri===this.playlist_.uri||u0&&this.remove(0,t)}},{key:"createSimplifiedSegmentObj_",value:function(e){var t=e.segment,i={resolvedUri:t.resolvedUri,byterange:t.byterange,requestId:e.requestId};if(t.key){var n=t.key.iv||new Uint32Array([0,0,0,e.mediaIndex+e.playlist.mediaSequence]);i.key={resolvedUri:t.key.resolvedUri,iv:n}}return t.map&&(i.map=this.initSegment(t.map)),i}},{key:"segmentRequestFinished_",value:function(e,t){if(this.mediaRequests+=1,t.stats&&(this.mediaBytesTransferred+=t.stats.bytesReceived,this.mediaTransferDuration+=t.stats.roundTripTime),!this.pendingSegment_)return void(this.mediaRequestsAborted+=1);if(t.requestId===this.pendingSegment_.requestId){if(e)return this.pendingSegment_=null,this.state="READY",e.code===T.REQUEST_ERRORS.ABORTED?void(this.mediaRequestsAborted+=1):(this.pause(),e.code===T.REQUEST_ERRORS.TIMEOUT?(this.mediaRequestsTimedout+=1,this.bandwidth=1,this.roundTrip=NaN,void this.trigger("bandwidthupdate")):(this.mediaRequestsErrored+=1,this.error(e),void this.trigger("error")));this.bandwidth=t.stats.bandwidth,this.roundTrip=t.stats.roundTripTime,t.map&&(t.map=this.initSegment(t.map,!0)),this.processSegmentResponse_(t)}}},{key:"processSegmentResponse_",value:function(e){var t=this.pendingSegment_;t.bytes=e.bytes,e.map&&(t.segment.map.bytes=e.map.bytes),t.endOfAllRequests=e.endOfAllRequests,this.handleSegment_()}},{key:"handleSegment_",value:function(){var e=this;if(!this.pendingSegment_)return void(this.state="READY");var t=this.pendingSegment_,i=t.segment,n=this.syncController_.probeSegmentInfo(t);"undefined"==typeof this.startingMedia_&&n&&(n.containsAudio||n.containsVideo)&&(this.startingMedia_={containsAudio:n.containsAudio,containsVideo:n.containsVideo});var r=E(this.loaderType_,this.startingMedia_,n);if(r)return this.error({message:r,blacklistDuration:Infinity}),void this.trigger("error");if(t.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");null!==t.timestampOffset&&t.timestampOffset!==this.sourceUpdater_.timestampOffset()&&(this.sourceUpdater_.timestampOffset(t.timestampOffset),this.trigger("timestampoffset"));var a=this.syncController_.mappingForTimeline(t.timeline);null!==a&&this.trigger({type:"segmenttimemapping",mapping:a}),this.state="APPENDING",i.map&&function(){var t=(0,b.initSegmentId)(i.map);if(!e.activeInitSegmentId_||e.activeInitSegmentId_!==t){var n=e.initSegment(i.map);e.sourceUpdater_.appendBuffer(n.bytes,function(){e.activeInitSegmentId_=t})}}(),t.byteLength=t.bytes.byteLength,"number"==typeof i.start&&"number"==typeof i.end?this.mediaSecondsLoaded+=i.end-i.start:this.mediaSecondsLoaded+=i.duration,this.sourceUpdater_.appendBuffer(t.bytes,this.handleUpdateEnd_.bind(this))}},{key:"handleUpdateEnd_",value:function(){if(this.logger_("handleUpdateEnd_","segmentInfo:",this.pendingSegment_),!this.pendingSegment_)return this.state="READY",void(this.paused()||this.monitorBuffer_());var e=this.pendingSegment_,t=e.segment,i=null!==this.mediaIndex;if(this.pendingSegment_=null,this.recordThroughput_(e),this.addSegmentMetadataCue_(e),this.state="READY",this.mediaIndex=e.mediaIndex,this.fetchAtBuffer_=!0,this.currentTimeline_=e.timeline,this.trigger("syncinfoupdate"),t.end&&this.currentTime_()-t.end>3*e.playlist.targetDuration)return void this.resetEverything();i&&this.trigger("bandwidthupdate"),this.trigger("progress"),k(e.playlist,this.mediaSource_,e.mediaIndex+1)&&this.endOfStream(),this.paused()||this.monitorBuffer_()}},{key:"recordThroughput_",value:function(e){var t=this.throughput.rate,i=Date.now()-e.endOfAllRequests+1,n=Math.floor(e.byteLength/i*8*1e3);this.throughput.rate+=(n-t)/++this.throughput.count}},{key:"logger_",value:function(){}},{key:"addSegmentMetadataCue_",value:function(e){if(this.segmentMetadataTrack_){var t=e.segment,i=t.start,n=t.end;if(O(i)&&O(n)){(0,v["default"])(i,n,this.segmentMetadataTrack_);var r=y["default"].WebKitDataCue||y["default"].VTTCue,a={uri:e.uri,timeline:e.timeline,playlist:e.playlist.uri,start:i,end:n},s=JSON.stringify(a),o=new r(i,n,s);o.value=a,this.segmentMetadataTrack_.addCue(o)}}}}]),t}(f["default"].EventTarget);i["default"]=L}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],17:[function(e,t,i){(function(e){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(i,"__esModule",{value:!0});var r=function(){function e(e,t){for(var i=0;i=l)&&(o=l,s={time:d.start,segmentIndex:u})}}return s}},{name:"Discontinuity",run:function(e,t,i,n,r){var a=null;if(r=r||0,t.discontinuityStarts&&t.discontinuityStarts.length)for(var s=null,o=0;o=f)&&(s=f,a={time:l.time,segmentIndex:u})}}return a}},{name:"Playlist",run:function(e,t,i,n,r){if(t.syncInfo){return{time:t.syncInfo.time,segmentIndex:t.syncInfo.mediaSequence-t.mediaSequence}}return null}}];i.syncPointStrategies=p;var m=function(e){function t(){var e=arguments.length<=0||arguments[0]===undefined?{}:arguments[0];r(this,t),o(Object.getPrototypeOf(t.prototype),"constructor",this).call(this),this.inspectCache_=undefined,this.timelines=[],this.discontinuities=[],this.datetimeToDisplayTime=null,e.debug&&(this.logger_=h["default"].log.bind(h["default"],"sync-controller ->"))}return a(t,e),s(t,[{key:"getSyncPoint",value:function(e,t,i,n){var r=this.runStrategies_(e,t,i,n);return r.length?this.selectSyncPoint_(r,{key:"time",value:n}):null}},{key:"getExpiredTime",value:function(e,t){if(!e||!e.segments)return null;var i=this.runStrategies_(e,t,e.discontinuitySequence,0);if(!i.length)return null;var n=this.selectSyncPoint_(i,{key:"segmentIndex",value:0});return n.segmentIndex>0&&(n.time*=-1),Math.abs(n.time+(0,f.sumDurations)(e,n.segmentIndex,0))}},{key:"runStrategies_",value:function(e,t,i,n){for(var r=[],a=0;a:",o))}return r}},{key:"selectSyncPoint_",value:function(e,t){for(var i=e[0].syncPoint,n=Math.abs(e[0].syncPoint[t.key]-t.value),r=e[0].strategy,a=1;a chosen: ",i),i}},{key:"saveExpiredSegmentInfo",value:function(e,t){for(var i=t.mediaSequence-e.mediaSequence,n=i-1;n>=0;n--){var r=e.segments[n];if(r&&"undefined"!=typeof r.start){t.syncInfo={mediaSequence:e.mediaSequence+n,time:r.start},this.logger_("playlist sync:",t.syncInfo),this.trigger("syncinfoupdate");break}}}},{key:"setDateTimeMapping",value:function(e){if(!this.datetimeToDisplayTime&&e.dateTimeObject){var t=e.dateTimeObject.getTime()/1e3;this.datetimeToDisplayTime=-t}}},{key:"reset",value:function(){this.inspectCache_=undefined}},{key:"probeSegmentInfo",value:function(e){var t=e.segment,i=e.playlist,n=undefined;return n=t.map?this.probeMp4Segment_(e):this.probeTsSegment_(e),n&&this.calculateSegmentTimeMapping_(e,n)&&(this.saveDiscontinuitySyncInfo_(e),i.syncInfo||(i.syncInfo={mediaSequence:i.mediaSequence+e.mediaIndex,time:t.start})),n}},{key:"probeMp4Segment_",value:function(e){var t=e.segment,i=d["default"].timescale(t.map.bytes),n=d["default"].startTime(i,e.bytes);return null!==e.timestampOffset&&(e.timestampOffset-=n),{start:n,end:n+t.duration}}},{key:"probeTsSegment_",value:function(e){var t=(0,l.inspect)(e.bytes,this.inspectCache_),i=undefined,n=undefined;return t?(t.video&&2===t.video.length?(this.inspectCache_=t.video[1].dts,i=t.video[0].dtsTime,n=t.video[1].dtsTime):t.audio&&2===t.audio.length&&(this.inspectCache_=t.audio[1].dts,i=t.audio[0].dtsTime,n=t.audio[1].dtsTime),{start:i,end:n,containsVideo:t.video&&2===t.video.length,containsAudio:t.audio&&2===t.audio.length}):null}},{key:"timestampOffsetForTimeline",value:function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].time}},{key:"mappingForTimeline",value:function(e){return"undefined"==typeof this.timelines[e]?null:this.timelines[e].mapping}},{key:"calculateSegmentTimeMapping_",value:function(e,t){var i=e.segment,n=this.timelines[e.timeline];if(null!==e.timestampOffset)this.logger_("tsO:",e.timestampOffset),n={time:e.startOfSegment,mapping:e.startOfSegment-t.start},this.timelines[e.timeline]=n,this.trigger("timestampoffset"),i.start=e.startOfSegment,i.end=t.end+n.mapping;else{if(!n)return!1;i.start=t.start+n.mapping,i.end=t.end+n.mapping}return!0}},{key:"saveDiscontinuitySyncInfo_",value:function(e){var t=e.playlist,i=e.segment;if(i.discontinuity)this.discontinuities[i.timeline]={time:i.start,accuracy:0};else if(t.discontinuityStarts.length)for(var n=0;no){var u=undefined;u=s<0?i.start-(0,f.sumDurations)(t,e.mediaIndex,r):i.end+(0,f.sumDurations)(t,e.mediaIndex+1,r),this.discontinuities[a]={time:u,accuracy:o}}}}},{key:"logger_",value:function(){}}]),t}(h["default"].EventTarget);i["default"]=m}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],19:[function(e,t,i){"use strict";Object.defineProperty(i,"__esModule",{value:!0});var n=function(){var e=arguments.length<=0||arguments[0]===undefined?"":arguments[0],t={codecCount:0},i=undefined;return t.codecCount=e.split(",").length,t.codecCount=t.codecCount||2,i=/(^|\s|,)+(avc1)([^ ,]*)/i.exec(e),i&&(t.videoCodec=i[2],t.videoObjectTypeIndicator=i[3]),t.audioProfile=/(^|\s|,)+mp4a.[0-9A-Fa-f]+\.([0-9A-Fa-f]+)/i.exec(e),t.audioProfile=t.audioProfile&&t.audioProfile[2],t};i.parseCodecs=n},{}],20:[function(e,t,i){(function(n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(i,"__esModule",{value:!0});var o=function(){function e(e,t){for(var i=0;i>7))^a]=a;for(s=o=0;!n[s];s^=l||1,o=d[o]||1)for(h=o^o<<1^o<<2^o<<3^o<<4,h=h>>8^255&h^99,n[s]=h,r[h]=s,c=u[f=u[l=u[s]]],m=16843009*c^65537*f^257*l^16843008*s,p=257*u[h]^16843008*h,a=0;a<4;a++)t[a][s]=p=p<<24^p>>>8,i[a][h]=m=m<<24^m>>>8;for(a=0;a<5;a++)t[a]=t[a].slice(0),i[a]=i[a].slice(0);return e},s=null,o=function(){function e(t){n(this,e),s||(s=a()),this._tables=[[s[0][0].slice(),s[0][1].slice(),s[0][2].slice(),s[0][3].slice(),s[0][4].slice()],[s[1][0].slice(),s[1][1].slice(),s[1][2].slice(),s[1][3].slice(),s[1][4].slice()]];var i=undefined,r=undefined,o=undefined,u=undefined,d=undefined,l=this._tables[0][4],f=this._tables[1],c=t.length,h=1;if(4!==c&&6!==c&&8!==c)throw new Error("Invalid aes key size");for(u=t.slice(0),d=[],this._key=[u,d],i=c;i<4*c+28;i++)o=u[i-1],(i%c==0||8===c&&i%c==4)&&(o=l[o>>>24]<<24^l[o>>16&255]<<16^l[o>>8&255]<<8^l[255&o],i%c==0&&(o=o<<8^o>>>24^h<<24,h=h<<1^283*(h>>7))),u[i]=u[i-c]^o;for(r=0;i;r++,i--)o=u[3&r?i:i-4],d[r]=i<=4||r<4?o:f[0][l[o>>>24]]^f[1][l[o>>16&255]]^f[2][l[o>>8&255]]^f[3][l[255&o]]}return r(e,[{key:"decrypt",value:function(e,t,i,n,r,a){var s=this._key[1],o=e^s[0],u=n^s[1],d=i^s[2],l=t^s[3],f=undefined,c=undefined,h=undefined,p=s.length/4-2,m=undefined,g=4,y=this._tables[1],_=y[0],v=y[1],b=y[2],T=y[3],S=y[4];for(m=0;m
\n"
"\n"
-#: core/views.py:242
+#: core/views.py:246
msgid "your message intitled"
msgstr "Votre message intitulé"
-#: core/views.py:247
+#: core/views.py:251
msgid "Your message has been sent."
msgstr "Votre message a bien été envoyé"
-#: core/views.py:254 core/views.py:264
+#: core/views.py:258 core/views.py:273
msgid "Password request for : "
msgstr "Mot de passe requis pour : "
-#: core/views.py:274
+#: core/views.py:270
+msgid "The video id is not valid. Redirect to Contact Us form."
+msgstr ""
+"L'ID de la vidéo n'est pas valide. Redirection sur le formulaire Contactez-"
+"nous."
+
+#: core/views.py:283
msgid "Contact the owner"
msgstr "Contacter le propriétaire"
+#: core/views.py:316
+#, fuzzy
+#| msgid "The video id is not valid. Redirect to Contact Us form."
+msgid "The video id is not valid."
+msgstr ""
+"L'ID de la vidéo n'est pas valide. Redirection sur le formulaire Contactez-"
+"nous."
+
#: django_cas_gateway/views.py:156
#, python-format
msgid "You are logged in as %s."
@@ -1472,46 +1540,47 @@ msgstr "Doctorat"
msgid "Other"
msgstr "Autre"
-#: pods/admin.py:54 pods/models.py:82
+#: pods/admin.py:50 pods/models.py:84
msgid "Owners"
msgstr "Propriétaires"
-#: pods/admin.py:161
+#: pods/admin.py:175
msgid "Encode selected"
msgstr "(Ré)encoder la sélection"
-#: pods/forms.py:151
+#: pods/forms.py:167
msgid "Filetype not allowed! Filetypes allowed: "
msgstr "Type de fichier non admis ! Les types de fichiers acceptés sont : "
-#: pods/forms.py:157 pods/templates/videos/video_edit.html:471
+#: pods/forms.py:173 pods/templates/videos/video_edit.html:471
msgid "Date of the event"
msgstr "Date de l'évènement"
-#: pods/forms.py:159 pods/templates/videos/video_edit.html:442
+#: pods/forms.py:175 pods/templates/videos/video_edit.html:442
msgid "File"
msgstr "Fichier"
-#: pods/models.py:77 pods/models.py:121 pods/models.py:156 pods/models.py:186
+#: pods/models.py:79 pods/models.py:123 pods/models.py:158 pods/models.py:188
#: pods/templates/channels/channel.html:125
#: pods/templates/channels/channel.html:162
#: pods/templates/channels/channel.html:175
msgid "Headband"
msgstr "Bandeau"
-#: pods/models.py:79
+#: pods/models.py:81
msgid "Background color"
msgstr "Couleur de fond"
-#: pods/models.py:80
+#: pods/models.py:82
msgid "Extra style"
msgstr "Style supplémentaire"
-#: pods/models.py:88 pods/models.py:1299
+#: pods/models.py:90 pods/models.py:1314 pods/models.py:1341
+#: pods/templates/playlists/my_playlists.html:192
msgid "Visible"
msgstr "Visible"
-#: pods/models.py:90
+#: pods/models.py:92
msgid ""
"If checked, the channel appear in a list of available channels on the "
"platform."
@@ -1519,46 +1588,46 @@ msgstr ""
"Si cochée, la chaîne apparait dans la liste des chaînes disponibles sur la "
"plate-forme."
-#: pods/models.py:95 pods/models.py:123
-#: pods/templates/search/search_video.html:221
+#: pods/models.py:97 pods/models.py:125
+#: pods/templates/search/search_video.html:225
msgid "Channel"
msgstr "Chaîne"
-#: pods/models.py:137
+#: pods/models.py:139
msgid "Theme"
msgstr "Thème"
-#: pods/models.py:138 pods/models.py:294 pods/models.py:1296
+#: pods/models.py:140 pods/models.py:296 pods/models.py:1311
#: pods/templates/channels/channel.html:136
#: pods/templates/channels/channel_edit.html:95
#: pods/templates/videos/video_edit.html:590
msgid "Themes"
msgstr "Thèmes"
-#: pods/models.py:170 pods/models.py:288 pods/models.py:915
-#: pods/models.py:1290 pods/templates/search/search_video.html:184
+#: pods/models.py:172 pods/models.py:290 pods/models.py:930
+#: pods/models.py:1305 pods/templates/search/search_video.html:188
#: pods/templates/videos/enrich/list_enrich.html:35
-#: pods/templates/videos/video.html:481
+#: pods/templates/videos/video.html:540
#: pods/templates/videos/video_edit.html:538
msgid "Type"
msgstr "Type"
-#: pods/models.py:179 pods/models.py:787 pods/models.py:891
-#: pods/models.py:1046 pods/models.py:1160
+#: pods/models.py:181 pods/models.py:802 pods/models.py:906
+#: pods/models.py:1061 pods/models.py:1175
msgid "title"
msgstr "titre"
-#: pods/models.py:181 pods/models.py:789 pods/models.py:893
-#: pods/models.py:1048
+#: pods/models.py:183 pods/models.py:804 pods/models.py:908
+#: pods/models.py:1063
msgid "slug"
msgstr "titre court"
-#: pods/models.py:200 pods/templates/search/search_video.html:208
-#: pods/templates/videos/video.html:488
+#: pods/models.py:202 pods/templates/search/search_video.html:212
+#: pods/templates/videos/video.html:547
msgid "Discipline"
msgstr "Discipline"
-#: pods/models.py:286
+#: pods/models.py:288
msgid ""
"Separate tags with spaces, enclose the tags consist of several words in "
"quotation marks."
@@ -1566,23 +1635,23 @@ msgstr ""
"Séparez les mots-clés avec des espaces, placez les mots-clés constitués de "
"plusieurs mots entre guillemets."
-#: pods/models.py:299 pods/templates/videos/video_edit.html:609
+#: pods/models.py:301 pods/templates/videos/video_edit.html:609
msgid "Draft"
msgstr "Brouillon"
-#: pods/models.py:301
+#: pods/models.py:303
msgid ""
"If this box is checked, the video will be visible and accessible only by you."
msgstr ""
"Si cette case est cochée, la vidéo sera visible et accessible uniquement par "
"vous."
-#: pods/models.py:304 pods/models.py:1221
+#: pods/models.py:306 pods/models.py:1236
#: pods/templates/videos/video_edit.html:622
msgid "Restricted access"
msgstr "Accès restreint"
-#: pods/models.py:306
+#: pods/models.py:308
msgid ""
"If this box is checked, the video will only be accessible to authenticated "
"users."
@@ -1590,508 +1659,532 @@ msgstr ""
"Si cette case est cochée, la vidéo sera accessible uniquement par les "
"utilisateurs authentifiés."
-#: pods/models.py:309
+#: pods/models.py:311
msgid "password"
msgstr "Mot de passe"
-#: pods/models.py:311
+#: pods/models.py:313
msgid "Viewing this video will not be possible without this password."
msgstr ""
"Le visionnage de la vidéo ne pourra se faire qu'après avoir fourni ce mot de "
"passe."
-#: pods/models.py:552
+#: pods/models.py:566
msgid "encodingType"
msgstr "type d'encodage"
-#: pods/models.py:554
+#: pods/models.py:568
msgid "encodingFile"
msgstr "Fichier résultant"
-#: pods/models.py:562
+#: pods/models.py:577
msgid "Format"
msgstr "format"
-#: pods/models.py:570
+#: pods/models.py:585
msgid "encoding"
msgstr "encodage"
-#: pods/models.py:571
+#: pods/models.py:586
msgid "encodings"
msgstr "encodages"
-#: pods/models.py:589
+#: pods/models.py:604
msgid "lastname / firstname"
msgstr "Nom / Prénom"
-#: pods/models.py:591
+#: pods/models.py:606
msgid "mail"
msgstr "courriel"
-#: pods/models.py:593
+#: pods/models.py:608
msgid "actor"
msgstr "acteur"
-#: pods/models.py:594
+#: pods/models.py:609
msgid "author"
msgstr "auteur"
-#: pods/models.py:595
+#: pods/models.py:610
msgid "designer"
msgstr "concepteur"
-#: pods/models.py:596
+#: pods/models.py:611
msgid "consultant"
msgstr "consultant"
-#: pods/models.py:597
+#: pods/models.py:612
msgid "contributor"
msgstr "contributeur"
-#: pods/models.py:598
+#: pods/models.py:613
msgid "editor"
msgstr "éditeur"
-#: pods/models.py:599
+#: pods/models.py:614
msgid "speaker"
msgstr "intervenant"
-#: pods/models.py:600
+#: pods/models.py:615
msgid "soundman"
msgstr "preneur de son"
-#: pods/models.py:601
+#: pods/models.py:616
msgid "director"
msgstr "réalisateur"
-#: pods/models.py:602
+#: pods/models.py:617
msgid "writer"
msgstr "scénariste"
-#: pods/models.py:603
+#: pods/models.py:618
msgid "technician"
msgstr "technicien"
-#: pods/models.py:604
+#: pods/models.py:619
msgid "voice-over"
msgstr "voix-off"
-#: pods/models.py:607
+#: pods/models.py:622
msgid "role"
msgstr "rôle"
-#: pods/models.py:612
+#: pods/models.py:627
msgid "Contributor Pod"
msgstr "Contributeur"
-#: pods/models.py:613
+#: pods/models.py:628
msgid "Contributors Pod"
msgstr "Contributeurs"
-#: pods/models.py:625
+#: pods/models.py:640
msgid "please enter a name from 2 to 200 caracteres."
msgstr "Veuillez renseigner un titre contenant entre 2 et 100 caractères. "
-#: pods/models.py:628
+#: pods/models.py:643
msgid "you cannot enter a weblink with more than 200 caracteres."
msgstr "les liens internet doivent être inférieur à 200 caractères. "
-#: pods/models.py:630
+#: pods/models.py:645
msgid "please enter a role."
msgstr "Veuillez renseigner un rôle."
-#: pods/models.py:645
+#: pods/models.py:660
msgid "there is already a contributor with the same name and role in the list."
msgstr "Un contributeur avec le même nom et le même role existe déjà."
-#: pods/models.py:667
+#: pods/models.py:682
msgid "subtitles"
msgstr "sous-titres"
-#: pods/models.py:668
+#: pods/models.py:683
msgid "captions"
msgstr "légendes"
-#: pods/models.py:671
+#: pods/models.py:686
#: pods/templates/videos/completion/subtitle/list_subtitle.html:33
msgid "Kind"
msgstr "Genre"
-#: pods/models.py:676
+#: pods/models.py:691
msgid "subtitle file"
msgstr "fichier de sous-titres"
-#: pods/models.py:679
+#: pods/models.py:694
msgid "Track Pod"
msgstr "Piste"
-#: pods/models.py:680
+#: pods/models.py:695
msgid "Tracks Pod"
msgstr "Pistes"
-#: pods/models.py:692
+#: pods/models.py:707
msgid "please enter a correct kind."
msgstr "veuillez renseigner le type de piste."
-#: pods/models.py:694
+#: pods/models.py:709
msgid "please enter a correct lang."
msgstr "veuillez renseigner une langue."
-#: pods/models.py:696
+#: pods/models.py:711
msgid "please specify a track file."
msgstr "veuillez spécifier un fichier de sous-titre ou de légende."
-#: pods/models.py:698
+#: pods/models.py:713
msgid "only “.vtt” format is allowed."
msgstr "seul le format « .vtt » est autorisé."
-#: pods/models.py:713
+#: pods/models.py:728
msgid ""
"there is already a subtitle with the same kind and language in the list."
msgstr "un sous-titrage de même nature et de même langue existe déjà."
-#: pods/models.py:730
+#: pods/models.py:745
msgid "Document Pod"
msgstr "Document"
-#: pods/models.py:731
+#: pods/models.py:746
msgid "Documents Pod"
msgstr "Documents"
-#: pods/models.py:748
+#: pods/models.py:763
msgid "please enter a document "
msgstr "veuillez sélectionner un document "
-#: pods/models.py:764
+#: pods/models.py:779
msgid "this document is already contained in the list."
msgstr "Ce document a déjà été envoyé."
-#: pods/models.py:776
+#: pods/models.py:791
msgid "top-left"
-msgstr ""
+msgstr "haut à gauche"
-#: pods/models.py:777
+#: pods/models.py:792
msgid "top"
-msgstr ""
+msgstr "haut"
-#: pods/models.py:778
+#: pods/models.py:793
msgid "top-right"
-msgstr ""
+msgstr "haut à droite"
-#: pods/models.py:779
+#: pods/models.py:794
msgid "right"
-msgstr ""
+msgstr "droite"
-#: pods/models.py:780
+#: pods/models.py:795
msgid "bottom-right"
-msgstr ""
+msgstr "bas à droite"
-#: pods/models.py:781
+#: pods/models.py:796
msgid "bottom"
-msgstr ""
+msgstr "bas"
-#: pods/models.py:782
+#: pods/models.py:797
msgid "bottom-left"
-msgstr ""
+msgstr "bas à gauche"
-#: pods/models.py:783
+#: pods/models.py:798
msgid "left"
-msgstr ""
+msgstr "gauche"
-#: pods/models.py:794 pods/models.py:1053
+#: pods/models.py:809 pods/models.py:1068
#: pods/templates/videos/chapter/list_chapter.html:35
msgid "Start time"
msgstr "Début"
-#: pods/models.py:795
+#: pods/models.py:810
msgid "Start time of the overlay, in seconds."
msgstr "Début de la superposition, en secondes."
-#: pods/models.py:797
+#: pods/models.py:812
msgid "End time"
msgstr "Temps de fin"
-#: pods/models.py:798
+#: pods/models.py:813
msgid "End time of the overlay, in seconds."
msgstr "Début de la superposition, en secondes."
-#: pods/models.py:800
+#: pods/models.py:815
msgid "Content"
msgstr "Contenu"
-#: pods/models.py:802
+#: pods/models.py:817
msgid "Content of the overlay"
msgstr "Contenu de la superposition"
-#: pods/models.py:804
+#: pods/models.py:819 pods/models.py:1376
+#: pods/templates/playlists/my_playlists.html:197
#: pods/templates/videos/completion/overlay/list_overlay.html:36
msgid "Position"
msgstr "Position"
-#: pods/models.py:806
+#: pods/models.py:821
msgid "Position of the overlay"
msgstr "Emplacement de la superposition"
-#: pods/models.py:807
+#: pods/models.py:822
msgid "Show background"
msgstr "Afficher l'arrière plan"
-#: pods/models.py:808
+#: pods/models.py:823
msgid "Show the background of the overlay"
msgstr "Affiche l'arrière plan de la superposition"
-#: pods/models.py:811
+#: pods/models.py:826
msgid "Overlay"
msgstr "Superposition"
-#: pods/models.py:812
+#: pods/models.py:827
msgid "Overlays"
msgstr "Superpositions"
-#: pods/models.py:830 pods/models.py:954 pods/models.py:1077
+#: pods/models.py:845 pods/models.py:969 pods/models.py:1092
#: pods/templates/videos/video_chapter.html:271
#: pods/templates/videos/video_enrich.html:327
msgid "Please enter a title from 2 to 100 characters."
msgstr "Veuillez renseigner un titre contenant entre 2 et 100 caractères."
-#: pods/models.py:840
+#: pods/models.py:855
msgid ""
"The value of the time start field is greater than the value of the end time "
"field."
msgstr "La valeur du commencement ne peut être supérieure à celle de la fin."
-#: pods/models.py:843
+#: pods/models.py:858
msgid "The value of time end field is greater than the video duration."
msgstr ""
"La valeur de fin de superposition est supérieure à la durée de la vidéo."
-#: pods/models.py:846
+#: pods/models.py:861
msgid "Time end field and time start field can't be equal."
msgstr "Le commencement et la fin ne peuvent être équivalents."
-#: pods/models.py:863
+#: pods/models.py:878
msgid "There is an overlap with the overlay "
msgstr "Il y a un chevauchement avec la superposition "
-#: pods/models.py:898
+#: pods/models.py:913
msgid "Stop video"
msgstr "Arrêter la lecture"
-#: pods/models.py:899
+#: pods/models.py:914
msgid "The video will pause when displaying this enrichment."
msgstr "La vidéo se met en pause lors de l'affichage de cet enrichissement."
-#: pods/models.py:901
+#: pods/models.py:916
#: pods/templates/videos/completion/overlay/list_overlay.html:34
#: pods/templates/videos/enrich/list_enrich.html:36
msgid "Start"
msgstr "Début"
-#: pods/models.py:902
+#: pods/models.py:917
msgid "Start of enrichment display in seconds"
msgstr "Début d'affichage de l'enrichissement en secondes"
-#: pods/models.py:904
+#: pods/models.py:919
#: pods/templates/videos/completion/overlay/list_overlay.html:35
#: pods/templates/videos/enrich/list_enrich.html:37
msgid "End"
msgstr "Fin"
-#: pods/models.py:905
+#: pods/models.py:920
msgid "End of enrichment display in seconds"
msgstr "Fin d'affichage de l'enrichissement en secondes"
-#: pods/models.py:908
+#: pods/models.py:923
msgid "image"
msgstr "image"
-#: pods/models.py:909 pods/models.py:919
+#: pods/models.py:924 pods/models.py:934
msgid "richtext"
msgstr "texte enrichi et mis en forme"
-#: pods/models.py:910
+#: pods/models.py:925
msgid "weblink"
msgstr "lien web"
-#: pods/models.py:911
+#: pods/models.py:926
msgid "document"
msgstr "document"
-#: pods/models.py:912
+#: pods/models.py:927
msgid "embed"
msgstr "intégrer"
-#: pods/models.py:925
+#: pods/models.py:940
msgid "Integrate an document (PDF, text, html)"
msgstr "Afficher un document (PDF, texte ou html)"
-#: pods/models.py:927
+#: pods/models.py:942
msgid "Embed"
msgstr "Intégrer"
-#: pods/models.py:929
+#: pods/models.py:944
msgid "Integrate an external source"
msgstr "Afficher une source externe (video youtube par exemple)"
-#: pods/models.py:932
+#: pods/models.py:947
msgid "Enrichment"
msgstr "Enrichissement"
-#: pods/models.py:933
+#: pods/models.py:948
msgid "Enrichments"
msgstr "Enrichissements"
-#: pods/models.py:957 pods/models.py:1080
+#: pods/models.py:972 pods/models.py:1095
#, python-format
msgid "Please enter a correct start field between 0 and %(duration)s."
msgstr ""
"Veuillez renseigner une valeur de début d'enrichissement comprise entre 0 et "
"%(duration)s."
-#: pods/models.py:961
+#: pods/models.py:976
#, python-format
msgid "Please enter a correct end field between 1 and %(duration)s."
msgstr ""
"Veuillez renseigner une valeur de fin d'enrichissement comprise entre 1 et "
"%(duration)s."
-#: pods/models.py:965 pods/templates/videos/video_enrich.html:345
+#: pods/models.py:980 pods/templates/videos/video_enrich.html:345
msgid "Please enter a correct image."
msgstr "Veuillez renseigner une image."
-#: pods/models.py:969 pods/templates/videos/video_enrich.html:352
+#: pods/models.py:984 pods/templates/videos/video_enrich.html:352
msgid "Please enter a correct richtext."
msgstr "Veuillez renseigner un texte."
-#: pods/models.py:973 pods/templates/videos/video_enrich.html:359
+#: pods/models.py:988 pods/templates/videos/video_enrich.html:359
msgid "Please enter a correct weblink."
msgstr "Veuillez renseigner un lien internet."
-#: pods/models.py:977 pods/templates/videos/video_completion.html:428
+#: pods/models.py:992 pods/templates/videos/video_completion.html:428
#: pods/templates/videos/video_enrich.html:372
msgid "Please select a document."
msgstr "Veuillez sélectionner un document."
-#: pods/models.py:981 pods/templates/videos/video_enrich.html:379
+#: pods/models.py:996 pods/templates/videos/video_enrich.html:379
msgid "Please enter a correct embed."
msgstr "Veuillez renseigner un code embed."
-#: pods/models.py:983 pods/templates/videos/video_enrich.html:391
+#: pods/models.py:998 pods/templates/videos/video_enrich.html:391
msgid "Please enter a type in index field."
msgstr "Veuillez choisir un type d'enrichissement."
-#: pods/models.py:995
+#: pods/models.py:1010
msgid "The value of the start field is greater than the value of end field."
msgstr "La valeur du commencement ne peut être supérieure à celle de la fin."
-#: pods/models.py:998
+#: pods/models.py:1013
msgid "The value of end field is greater than the video duration."
msgstr ""
"La valeur de fin d'enrichissement est supérieure à la durée de la vidéo."
-#: pods/models.py:1000
+#: pods/models.py:1015
msgid "End field and start field can't be equal."
msgstr "Le commencement et la fin ne peuvent être équivalents."
-#: pods/models.py:1018 pods/templates/videos/video_enrich.html:421
+#: pods/models.py:1033 pods/templates/videos/video_enrich.html:421
msgid "There is an overlap with the enrichment "
msgstr "Il y a un chevauchement avec l'enrichissement "
-#: pods/models.py:1054
+#: pods/models.py:1069
msgid "Start time of the chapter, in seconds."
msgstr "Début du chapitre, en secondes."
-#: pods/models.py:1057
+#: pods/models.py:1072
msgid "Chapter"
msgstr "Chapitre"
-#: pods/models.py:1058
+#: pods/models.py:1073
msgid "Chapters"
msgstr "Chapitres"
-#: pods/models.py:1098
+#: pods/models.py:1113
msgid "There is an overlap with the chapter "
msgstr "Il y a un chevauchement avec le chapitre "
-#: pods/models.py:1128
+#: pods/models.py:1143
msgid "Favorite"
msgstr "Favoris"
-#: pods/models.py:1129
+#: pods/models.py:1144
msgid "Favorites"
msgstr "Mes favoris"
-#: pods/models.py:1142 pods/models.py:1145
+#: pods/models.py:1157 pods/models.py:1160
msgid "Note"
msgstr "Note"
-#: pods/models.py:1168
+#: pods/models.py:1183
msgid "Mediacourse"
msgstr "Mediacours"
-#: pods/models.py:1169
+#: pods/models.py:1184
msgid "Mediacourses"
msgstr "Mediacours"
-#: pods/models.py:1203 pods/models.py:1210
+#: pods/models.py:1218 pods/models.py:1225
msgid "Building"
msgstr "Bâtiment"
-#: pods/models.py:1204
+#: pods/models.py:1219
msgid "Buildings"
msgstr "Bâtiments"
-#: pods/models.py:1212
+#: pods/models.py:1227
msgid "description"
msgstr "description"
-#: pods/models.py:1223
+#: pods/models.py:1238
msgid "Live is accessible only to authenticated users."
msgstr "La vidéo est accessible uniquement aux utilisateurs authentifiés."
-#: pods/models.py:1236
+#: pods/models.py:1251
msgid "Recorder"
msgstr "Enregistreur"
-#: pods/models.py:1237
+#: pods/models.py:1252
msgid "Recorders"
msgstr "Enregistreurs"
-#: pods/models.py:1245 pods/templates/videos/video.html:632
+#: pods/models.py:1260 pods/templates/videos/video.html:704
msgid "User"
msgstr "Utilisateur"
-#: pods/models.py:1248
+#: pods/models.py:1263
msgid "Answer"
msgstr "Réponse"
-#: pods/models.py:1264
+#: pods/models.py:1279
msgid "Report"
msgstr "Signaler"
-#: pods/models.py:1265
+#: pods/models.py:1280
msgid "Reports"
msgstr "Signalements"
-#: pods/models.py:1297
+#: pods/models.py:1312
msgid "Count items"
msgstr ""
-#: pods/models.py:1298
+#: pods/models.py:1313
msgid "Keep 0 to mean all items"
msgstr ""
-#: pods/models.py:1301
+#: pods/models.py:1316
msgid ""
"If this box is checked, the video will be visible and accessible by anyone."
msgstr ""
"Si cette case est cochée, la vidéo sera visible et accessible uniquement par "
"vous."
-#: pods/models.py:1305 pods/models.py:1306
+#: pods/models.py:1320 pods/models.py:1321
msgid "RSS"
msgstr ""
+#: pods/models.py:1343
+msgid "If checked, the playlist page becomes accessible from the user's card"
+msgstr ""
+"Si cette case est cochée, la page des playlists sera accessible par la fiche "
+"d'information de l'utilisateur"
+
+#: pods/models.py:1351 pods/templates/playlists/my_playlists.html:176
+msgid "Playlist"
+msgstr "Playlist"
+
+#: pods/models.py:1352 pods/templates/playlists/my_playlists.html:8
+#: pods/templates/videos/video.html:584
+msgid "Playlists"
+msgstr "Playlists"
+
+#: pods/models.py:1373
+msgid "playlist"
+msgstr "playlist"
+
+#: pods/models.py:1377
+msgid "Position of the video in a playlist."
+msgstr "Position de la vidéo dans la playlist."
+
#: pods/templates/channels/channel.html:61
#: pods/templates/disciplines/disciplines.html:50
#: pods/templates/favorites/my_favorites.html:20
@@ -2249,7 +2342,7 @@ msgstr "Ajouter un nouvel enregistrement"
#: pods/templates/videos/my_videos.html:32
#: pods/templates/videos/my_videos.html:43
#: pods/templates/videos/video_chapter.html:331
-#: pods/templates/videos/video_completion.html:458
+#: pods/templates/videos/video_completion.html:465
#: pods/templates/videos/video_delete.html:35
#: pods/templates/videos/video_edit.html:274
#: pods/templates/videos/video_enrich.html:445
@@ -2271,66 +2364,158 @@ msgstr[1] "%(counter)s utilisateurs ayant posté"
msgid "Show all"
msgstr "Tout afficher"
-#: pods/templates/search/search_video.html:74
+#: pods/templates/playlists/my_playlists.html:56
+msgid "Edit playlist"
+msgstr "Editer la playlist"
+
+#: pods/templates/playlists/my_playlists.html:75
+#: pods/templates/videos/video_completion.html:142
+msgid "Hide"
+msgstr "Cacher"
+
+#: pods/templates/playlists/my_playlists.html:84
+#: pods/templates/videos/video_completion.html:151
+msgid "Display"
+msgstr "Afficher"
+
+#: pods/templates/playlists/my_playlists.html:102
+#: pods/templates/playlists/my_playlists.html:270
+msgid "New playlist"
+msgstr "Nouvelle playlist"
+
+#: pods/templates/playlists/my_playlists.html:217
+msgid "Delete from playlist"
+msgstr "Supprimer de la playlist"
+
+#: pods/templates/playlists/my_playlists.html:217
+#: pods/templates/videos/completion/contributor/list_contributor.html:61
+#: pods/templates/videos/completion/download/list_download.html:54
+#: pods/templates/videos/completion/overlay/list_overlay.html:61
+#: pods/templates/videos/completion/subtitle/list_subtitle.html:59
+msgid "delete"
+msgstr "supprimer"
+
+#: pods/templates/playlists/my_playlists.html:226
+msgid "This playlist is empty"
+msgstr "Cette playlist est vide"
+
+#: pods/templates/playlists/my_playlists.html:235
+msgid "Edit the playlist"
+msgstr "Modifier la playlist"
+
+#: pods/templates/playlists/my_playlists.html:243
+msgid "Delete the playlist"
+msgstr "Supprimer la playlist"
+
+#: pods/templates/playlists/my_playlists.html:252
+msgid "Launch the playlist"
+msgstr "Lancer la playlist"
+
+#: pods/templates/playlists/my_playlists.html:283
+msgid ""
+"Your playlists can be shared to users who are at least authenticated on the "
+"site."
+msgstr ""
+
+#: pods/templates/playlists/my_playlists.html:284
+msgid "Users will only be able to see your playlists listed as \"visible\"."
+msgstr ""
+
+#: pods/templates/playlists/my_playlists.html:287
+msgid ""
+"You are currently on another user's playlists page. Only his playlists that "
+"he indicated as 'visible' are displayed here."
+msgstr ""
+
+#: pods/templates/playlists/playlist_body.html:46
+#: pods/templates/playlists/playlist_body.html:48
+msgid "Loop playlist"
+msgstr "Boucler la playlist"
+
+#: pods/templates/playlists/playlist_form.html:7
+#: pods/templates/videos/completion/contributor/form_contributor.html:27
+#: pods/templates/videos/completion/download/form_download.html:27
+#: pods/templates/videos/completion/overlay/form_overlay.html:27
+#: pods/templates/videos/completion/subtitle/form_subtitle.html:27
+msgid "Your form contains errors:"
+msgstr "Le formulaire contient des erreurs :"
+
+#: pods/templates/playlists/playlist_form.html:23
+#: pods/templates/videos/completion/contributor/form_contributor.html:43
+#: pods/templates/videos/completion/download/form_download.html:43
+#: pods/templates/videos/completion/overlay/form_overlay.html:43
+#: pods/templates/videos/completion/subtitle/form_subtitle.html:43
+msgid "save"
+msgstr "sauvegarder"
+
+#: pods/templates/playlists/playlist_form.html:24
+#: pods/templates/videos/completion/contributor/form_contributor.html:44
+#: pods/templates/videos/completion/download/form_download.html:44
+#: pods/templates/videos/completion/overlay/form_overlay.html:44
+#: pods/templates/videos/completion/subtitle/form_subtitle.html:44
+msgid "cancel"
+msgstr "annuler"
+
+#: pods/templates/search/search_video.html:78
msgid "Remove filters"
msgstr "Supprimer les filtres"
-#: pods/templates/search/search_video.html:80
+#: pods/templates/search/search_video.html:84
#, python-format
msgid "%(counter)s video found"
msgid_plural "%(counter)s videos found"
msgstr[0] "%(counter)s vidéo trouvée"
msgstr[1] "%(counter)s vidéos trouvées"
-#: pods/templates/search/search_video.html:88
+#: pods/templates/search/search_video.html:92
msgid "Search results"
msgstr "Résultat(s) de la recherche"
-#: pods/templates/search/search_video.html:109
+#: pods/templates/search/search_video.html:113
#: pods/templates/videos/videos_list.html:48
msgid "This content is only accessible to authenticated users."
msgstr "Ce contenu est uniquement accessible aux utilisateurs authentifiés."
-#: pods/templates/search/search_video.html:112
+#: pods/templates/search/search_video.html:116
#: pods/templates/videos/videos_list.html:51
msgid "This content is password protected."
msgstr "Ce contenu est protégé par mot de passe."
-#: pods/templates/search/search_video.html:115
+#: pods/templates/search/search_video.html:119
#: pods/templates/videos/videos_list.html:54
msgid "This content has enrichments (files, web links, etc.)."
msgstr "Ce contenu est enrichi (documents joints, liens web, etc.)."
-#: pods/templates/search/search_video.html:118
+#: pods/templates/search/search_video.html:122
#: pods/templates/videos/videos_list.html:57
msgid "This content is chaptered."
msgstr "Ce contenu est chapitré."
-#: pods/templates/search/search_video.html:121
+#: pods/templates/search/search_video.html:125
#: pods/templates/videos/videos_list.html:65
msgid "Video content."
msgstr "Contenu de type vidéo."
-#: pods/templates/search/search_video.html:123
+#: pods/templates/search/search_video.html:127
#: pods/templates/videos/videos_list.html:68
msgid "Audio content."
msgstr "Contenu de type audio."
-#: pods/templates/search/search_video.html:143
+#: pods/templates/search/search_video.html:147
msgid "No videos match your request."
msgstr "Aucune vidéo ne correspond à votre recherche."
-#: pods/templates/search/search_video.html:153
+#: pods/templates/search/search_video.html:157
msgid "Advanced Search"
msgstr "Recherche avancée"
-#: pods/templates/search/search_video.html:156
+#: pods/templates/search/search_video.html:160
#: pods/templates/videos/ownertools.html:25
-#: pods/templates/videos/video_interactive.html:175
+#: pods/templates/videos/video_interactive.html:173
msgid "Edit"
msgstr "Modifier"
-#: pods/templates/search/search_video.html:168
+#: pods/templates/search/search_video.html:172
msgid "faceting"
msgstr "Affiner"
@@ -2363,27 +2548,6 @@ msgstr "Modifier"
msgid "Delete the chapter"
msgstr "Supprimer le chapitre"
-#: pods/templates/videos/completion/contributor/form_contributor.html:27
-#: pods/templates/videos/completion/download/form_download.html:27
-#: pods/templates/videos/completion/overlay/form_overlay.html:27
-#: pods/templates/videos/completion/subtitle/form_subtitle.html:27
-msgid "Your form contains errors:"
-msgstr "Le formulaire contient des erreurs :"
-
-#: pods/templates/videos/completion/contributor/form_contributor.html:43
-#: pods/templates/videos/completion/download/form_download.html:43
-#: pods/templates/videos/completion/overlay/form_overlay.html:43
-#: pods/templates/videos/completion/subtitle/form_subtitle.html:43
-msgid "save"
-msgstr "sauvegarder"
-
-#: pods/templates/videos/completion/contributor/form_contributor.html:44
-#: pods/templates/videos/completion/download/form_download.html:44
-#: pods/templates/videos/completion/overlay/form_overlay.html:44
-#: pods/templates/videos/completion/subtitle/form_subtitle.html:44
-msgid "cancel"
-msgstr "annuler"
-
#: pods/templates/videos/completion/contributor/list_contributor.html:26
msgid "List of contributors"
msgstr "Liste des contributeurs"
@@ -2415,13 +2579,6 @@ msgstr "modifier"
msgid "Delete the contributor"
msgstr "Supprimer le contributeur"
-#: pods/templates/videos/completion/contributor/list_contributor.html:61
-#: pods/templates/videos/completion/download/list_download.html:54
-#: pods/templates/videos/completion/overlay/list_overlay.html:61
-#: pods/templates/videos/completion/subtitle/list_subtitle.html:59
-msgid "delete"
-msgstr "supprimer"
-
#: pods/templates/videos/completion/download/list_download.html:26
msgid "List of additional resources"
msgstr "Liste des documents complémentaires"
@@ -2478,15 +2635,15 @@ msgstr "Modifier l'enrichissement"
msgid "Delete the enrichment"
msgstr "Supprimer l'enrichissement"
-#: pods/templates/videos/extraheadplayer.html:76
+#: pods/templates/videos/extraheadplayer.html:80
msgid "please move your phone"
msgstr "Déplacer votre téléphone"
-#: pods/templates/videos/extraheadplayer.html:77
+#: pods/templates/videos/extraheadplayer.html:81
msgid "please use your mouse drag and drop the video"
msgstr "Utilisez votre souris pour vous déplacer dans la vidéo"
-#: pods/templates/videos/extraheadplayer.html:89
+#: pods/templates/videos/extraheadplayer.html:93
#, python-format
msgid "Access this content on “%(TITLE_SITE)s” in a new window / tab."
msgstr ""
@@ -2554,7 +2711,8 @@ msgstr "Interactivité"
msgid "Delete the video."
msgstr "Supprimer la vidéo."
-#: pods/templates/videos/video.html:64 pods/templates/videos/video.html:95
+#: pods/templates/videos/video.html:63 pods/templates/videos/video.html:92
+#: pods/templates/videos/video.html:122
#: pods/templates/videos/video_chapter.html:174
#: pods/templates/videos/video_chapter.html:200
#: pods/templates/videos/video_chapter.html:239
@@ -2564,166 +2722,180 @@ msgstr "Supprimer la vidéo."
msgid "You are no longer authenticated. Please log in again."
msgstr "Vous n'êtes plus authentifié. Veuillez vous reconnecter."
-#: pods/templates/videos/video.html:69 pods/templates/videos/video.html:114
+#: pods/templates/videos/video.html:68 pods/templates/videos/video.html:97
+#: pods/templates/videos/video.html:141
msgid "Error sending information."
msgstr "Erreur lors de l'envoi des informations."
-#: pods/templates/videos/video.html:69 pods/templates/videos/video.html:114
+#: pods/templates/videos/video.html:68 pods/templates/videos/video.html:97
+#: pods/templates/videos/video.html:141
msgid "No data could be given."
msgstr "Aucune données récupérées."
-#: pods/templates/videos/video.html:173 pods/templates/videos/video.html:653
+#: pods/templates/videos/video.html:200 pods/templates/videos/video.html:725
msgid "You got the following score on this video"
msgstr "Vous avez obtenu le score suivant"
-#: pods/templates/videos/video.html:183 pods/templates/videos/video.html:645
+#: pods/templates/videos/video.html:210 pods/templates/videos/video.html:717
msgid "No score available"
msgstr "Score non disponible"
-#: pods/templates/videos/video.html:282
+#: pods/templates/videos/video.html:324
msgid "This video is protected by password, please fill in and click send."
msgstr ""
"Cette vidéo est protégée par mot de passe, merci de le renseigner et de "
"cliquer sur « Envoyer »."
-#: pods/templates/videos/video.html:286
+#: pods/templates/videos/video.html:328
msgid "Password required"
msgstr "Mot de passe requis"
-#: pods/templates/videos/video.html:295
+#: pods/templates/videos/video.html:337
msgid "If you do not have the password for this content, please"
msgstr ""
"Si vous n'avez pas le mot de passe ou si vous avez des problèmes de connexion"
-#: pods/templates/videos/video.html:295
+#: pods/templates/videos/video.html:337
msgid "contact its owner"
msgstr "Contacter le propriétaire"
-#: pods/templates/videos/video.html:325 pods/templates/videos/video.html:327
+#: pods/templates/videos/video.html:367 pods/templates/videos/video.html:369
msgid "favorite"
msgstr "favoris"
-#: pods/templates/videos/video.html:330 pods/templates/videos/video.html:332
+#: pods/templates/videos/video.html:372 pods/templates/videos/video.html:374
msgid "Add to your favorites videos."
msgstr "ajouter à vos vidéos favorites."
-#: pods/templates/videos/video.html:341 pods/templates/videos/video.html:343
+#: pods/templates/videos/video.html:383 pods/templates/videos/video.html:385
msgid "You have already reported this video."
msgstr "Vous avez déjà signalé cette vidéo."
-#: pods/templates/videos/video.html:348 pods/templates/videos/video.html:350
+#: pods/templates/videos/video.html:390 pods/templates/videos/video.html:392
msgid "Report this video."
msgstr "Signaler cette vidéo."
-#: pods/templates/videos/video.html:362
+#: pods/templates/videos/video.html:404
+msgid "Add this video to one of your playlists."
+msgstr "Ajouter cette vidéo à l'une de vos playlists."
+
+#: pods/templates/videos/video.html:406
+msgid "Add to your playlist."
+msgstr "Ajouter à votre playlist."
+
+#: pods/templates/videos/video.html:421
msgid "You must be logged in to add this video to your favorites."
msgstr "Vous devez être connecté pour ajouter cette vidéo à vos favoris."
-#: pods/templates/videos/video.html:367
+#: pods/templates/videos/video.html:426
msgid "You must be logged in to report inappropriate content."
msgstr "Vous devez être connecté pour signaler cette vidéo."
-#: pods/templates/videos/video.html:372 pods/templates/videos/video.html:374
+#: pods/templates/videos/video.html:431 pods/templates/videos/video.html:433
msgid "View the original video"
msgstr "Voir la vidéo originale"
-#: pods/templates/videos/video.html:376 pods/templates/videos/video.html:378
+#: pods/templates/videos/video.html:435 pods/templates/videos/video.html:437
msgid "View the interactive video"
msgstr "Voir la vidéo interactive"
-#: pods/templates/videos/video.html:392
+#: pods/templates/videos/video.html:451
msgid "Summary"
msgstr "Résumé"
-#: pods/templates/videos/video.html:398
+#: pods/templates/videos/video.html:457
msgid "Infos"
msgstr "Informations"
-#: pods/templates/videos/video.html:405
+#: pods/templates/videos/video.html:464
msgid "Downloads"
msgstr "Télécharger"
-#: pods/templates/videos/video.html:413
+#: pods/templates/videos/video.html:472
msgid "Embed/Share"
msgstr "Intégrer / Partager"
-#: pods/templates/videos/video.html:420
+#: pods/templates/videos/video.html:479
msgid "Score"
msgstr "Table des scores"
-#: pods/templates/videos/video.html:429
+#: pods/templates/videos/video.html:488
msgid "Embed/Share (Private Mode)"
msgstr "intégrer/partager (mode privé)"
-#: pods/templates/videos/video.html:468 pods/templates/videos/videos.html:69
+#: pods/templates/videos/video.html:527 pods/templates/videos/videos.html:69
msgid "File missing"
msgstr "Fichier manquant"
-#: pods/templates/videos/video.html:478
+#: pods/templates/videos/video.html:537
msgid "Number of view(s)"
msgstr "Nombre de vues"
-#: pods/templates/videos/video.html:498
+#: pods/templates/videos/video.html:557
msgid "Updated on"
msgstr "Mise en ligne le"
-#: pods/templates/videos/video.html:503
+#: pods/templates/videos/video.html:562
msgid "Contributor(s): writers, directors, editors, designers…"
msgstr "Contributeur(s) : scénaristes, réalisateurs, éditeurs, concepteurs…"
-#: pods/templates/videos/video.html:508
+#: pods/templates/videos/video.html:567
msgid "send an email"
msgstr "envoyer un courriel"
-#: pods/templates/videos/video.html:516
+#: pods/templates/videos/video.html:575
msgid "go to his web link"
msgstr "se rendre à cette adresse web"
-#: pods/templates/videos/video.html:530
-msgid "Download the video"
-msgstr "Télécharger la vidéo"
+#: pods/templates/videos/video.html:603
+msgid "Video file(s)"
+msgstr "Fichier(s) vidéo"
-#: pods/templates/videos/video.html:568
+#: pods/templates/videos/video.html:614
+msgid "Audio file(s)"
+msgstr "Fichier(s) audio"
+
+#: pods/templates/videos/video.html:640
msgid "Social Networks"
msgstr "Réseaux Sociaux"
-#: pods/templates/videos/video.html:580 pods/templates/videos/video.html:670
+#: pods/templates/videos/video.html:652 pods/templates/videos/video.html:742
msgid "Copy the content of this text box and paste it in the page"
msgstr "Copiez le contenu de cette zone de texte et collez-le dans la page"
-#: pods/templates/videos/video.html:586 pods/templates/videos/video.html:676
+#: pods/templates/videos/video.html:658 pods/templates/videos/video.html:748
msgid "Video size"
msgstr "Taille"
-#: pods/templates/videos/video.html:597 pods/templates/videos/video.html:687
+#: pods/templates/videos/video.html:669 pods/templates/videos/video.html:759
msgid "Autoplay"
msgstr "Lecture automatique"
-#: pods/templates/videos/video.html:601 pods/templates/videos/video.html:691
+#: pods/templates/videos/video.html:673 pods/templates/videos/video.html:763
msgid "Interactive"
msgstr "Interactive"
-#: pods/templates/videos/video.html:609
+#: pods/templates/videos/video.html:681
msgid "Use this link to share the video"
msgstr "Utilisez ce lien pour partager la vidéo"
-#: pods/templates/videos/video.html:615 pods/templates/videos/video.html:705
+#: pods/templates/videos/video.html:687 pods/templates/videos/video.html:777
msgid "Start video"
msgstr "Début de la vidéo"
-#: pods/templates/videos/video.html:618 pods/templates/videos/video.html:708
+#: pods/templates/videos/video.html:690 pods/templates/videos/video.html:780
msgid "Check the box to indicate the beginning of playing desired."
msgstr "Cochez la case pour indiquer le début de lecture souhaité."
-#: pods/templates/videos/video.html:624
+#: pods/templates/videos/video.html:696
msgid "Scoreboard"
msgstr "Table des scores"
-#: pods/templates/videos/video.html:625
+#: pods/templates/videos/video.html:697
msgid "Click below to refresh the information."
msgstr "Cliquez ci-dessous pour actualiser les informations."
-#: pods/templates/videos/video.html:628
+#: pods/templates/videos/video.html:700
msgid ""
"The scoreboard displays the users who viewed your interactive video and "
"their results."
@@ -2731,21 +2903,21 @@ msgstr ""
"La table des scores affiche les utilisateurs ayant vues votre vidéo "
"interactive et leurs résultats."
-#: pods/templates/videos/video.html:657
+#: pods/templates/videos/video.html:729
msgid "This is the first time you watch this video."
msgstr "C'est la première fois que vous regardez cette vidéo."
-#: pods/templates/videos/video.html:699
+#: pods/templates/videos/video.html:771
msgid "Use this link to share the video in private mode"
msgstr "Utilisez ce lien pour partager la vidéo en mode privé"
-#: pods/templates/videos/video.html:738
+#: pods/templates/videos/video.html:810
msgid "You must be logged in to take notes."
msgstr "Vous devez être connecté pour prendre des notes."
-#: pods/templates/videos/video.html:747
+#: pods/templates/videos/video.html:819
#: pods/templates/videos/video_chapter.html:369
-#: pods/templates/videos/video_completion.html:556
+#: pods/templates/videos/video_completion.html:563
#: pods/templates/videos/video_enrich.html:483
msgid "Edit the video"
msgstr "Modifier la vidéo"
@@ -2797,9 +2969,9 @@ msgid "No data could be stored."
msgstr "Aucune donnée n'a pu être enregistrée."
#: pods/templates/videos/video_chapter.html:264
-#: pods/templates/videos/video_enrich.html:275 pods/views.py:227
-#: pods/views.py:574 pods/views.py:694 pods/views.py:887 pods/views.py:889
-#: pods/views.py:979
+#: pods/templates/videos/video_enrich.html:275 pods/views.py:230
+#: pods/views.py:579 pods/views.py:745 pods/views.py:1074 pods/views.py:1076
+#: pods/views.py:1173
msgid "The changes have been saved."
msgstr "Les modifications ont été enregistrées."
@@ -2853,19 +3025,11 @@ msgid "You must save your chapters to view the result."
msgstr "Vous devez sauvegarder pour visualiser le résultat."
#: pods/templates/videos/video_completion.html:29
-#: pods/templates/videos/video_completion.html:447
-#: pods/templates/videos/video_completion.html:459
+#: pods/templates/videos/video_completion.html:454
+#: pods/templates/videos/video_completion.html:466
msgid "Completion video"
msgstr "Complétion de la vidéo "
-#: pods/templates/videos/video_completion.html:142
-msgid "Hide"
-msgstr "Cacher"
-
-#: pods/templates/videos/video_completion.html:151
-msgid "Display"
-msgstr "Afficher"
-
#: pods/templates/videos/video_completion.html:245
#: pods/templates/videos/video_completion.html:278
#: pods/templates/videos/video_completion.html:316
@@ -2945,55 +3109,59 @@ msgid ""
"There is already a download with this same name of document in the list."
msgstr "Il y a déjà un document à télécharger portant le même nom."
-#: pods/templates/videos/video_completion.html:468
+#: pods/templates/videos/video_completion.html:444
+msgid "Iframe and Script tags are not allowed."
+msgstr "Les balises Iframe et Script ne sont pas autorisées."
+
+#: pods/templates/videos/video_completion.html:475
msgid "Display "Contributor(s)" section"
msgstr "Afficher la section des contributeurs"
-#: pods/templates/videos/video_completion.html:469
+#: pods/templates/videos/video_completion.html:476
msgid "Contributor(s)"
msgstr "Contributeurs"
-#: pods/templates/videos/video_completion.html:487
+#: pods/templates/videos/video_completion.html:494
msgid "Add a new contributor"
msgstr "Ajouter un nouveau contributeur"
-#: pods/templates/videos/video_completion.html:492
+#: pods/templates/videos/video_completion.html:499
msgid "Display "Subtitle(s) and Captions(s) " section"
msgstr "Afficher la section de sous-titre ou de légende"
-#: pods/templates/videos/video_completion.html:492
+#: pods/templates/videos/video_completion.html:499
msgid "Subtitle(s) and caption(s)"
msgstr "Sous-titre(s) et légende(s)"
-#: pods/templates/videos/video_completion.html:508
+#: pods/templates/videos/video_completion.html:515
msgid "Add a new subtitle or caption file"
msgstr "Ajouter un nouveau fichier de sous-titre ou de légende"
-#: pods/templates/videos/video_completion.html:512
+#: pods/templates/videos/video_completion.html:519
msgid "Display " Additional resource(s)" section"
msgstr "Afficher la section documents complémentaires"
-#: pods/templates/videos/video_completion.html:512
+#: pods/templates/videos/video_completion.html:519
msgid "Additional resource(s)"
msgstr "Document(s) complémentaire(s)"
-#: pods/templates/videos/video_completion.html:527
+#: pods/templates/videos/video_completion.html:534
msgid "Add a new additional resource"
msgstr "Ajouter un nouveau document à télécharger"
-#: pods/templates/videos/video_completion.html:531
+#: pods/templates/videos/video_completion.html:538
msgid "Display " Overlay(s)" section"
msgstr "Afficher la section des superpositions"
-#: pods/templates/videos/video_completion.html:531
+#: pods/templates/videos/video_completion.html:538
msgid "Overlay(s)"
msgstr "Superposition(s)"
-#: pods/templates/videos/video_completion.html:545
+#: pods/templates/videos/video_completion.html:552
msgid "Add a new overlay"
msgstr "Ajouter une nouvelle superposition"
-#: pods/templates/videos/video_completion.html:567
+#: pods/templates/videos/video_completion.html:574
msgid ""
"Several web sites allows you to subtitle or caption videos (for example: "
"Amara)."
@@ -3001,7 +3169,7 @@ msgstr ""
"Plusieurs sites Web offrent des outils pour sous-titrer ou légender des "
"vidéos (Par exemple : Amara)."
-#: pods/templates/videos/video_completion.html:568
+#: pods/templates/videos/video_completion.html:575
msgid ""
"You can add several subtitle or caption files to a single video (for "
"example, in order to subtitle or caption this video in several languages)."
@@ -3009,11 +3177,11 @@ msgstr ""
"Vous pouvez ajouter plusieurs fichiers de sous-titre ou de légende pour une "
"même vidéo (par exemple, vous pouvez sous-titrer en plusieurs langues)."
-#: pods/templates/videos/video_completion.html:569
+#: pods/templates/videos/video_completion.html:576
msgid "Those files must be in “.vtt” format."
msgstr "Ces fichiers doivent être au format « .vtt »."
-#: pods/templates/videos/video_completion.html:570
+#: pods/templates/videos/video_completion.html:577
msgid ""
"For this purpose, you will need the URL of your video. This URL is a direct "
"access to this video. Please do not communicate it outside of this site in "
@@ -3024,7 +3192,7 @@ msgstr ""
"Evitez de la communiquer en dehors de ce site pour éviter tout "
"téléchargement et utilisation abusive."
-#: pods/templates/videos/video_completion.html:572
+#: pods/templates/videos/video_completion.html:579
msgid ""
"Overlay allows you to display text (with or without html tag) over the video "
"at specific times."
@@ -3032,7 +3200,7 @@ msgstr ""
"La superposition vous permet d'afficher du texte (avec ou sans balise html) "
"par dessus la vidéo à des moments spécifiques."
-#: pods/templates/videos/video_completion.html:575
+#: pods/templates/videos/video_completion.html:582
msgid ""
"Your current permissions do not allow you to add subtitle files, overlays or "
"documents to download videos. Please contact us to add these rights."
@@ -3115,7 +3283,7 @@ msgid "Please, specify a type."
msgstr "Veuillez spécifier un type."
#: pods/templates/videos/video_edit.html:292
-#: pods/templates/videos/video_player.html:130
+#: pods/templates/videos/video_player.html:136
msgid "The video is currently being encoded."
msgstr "Cette vidéo est en cours d'encodage."
@@ -3148,7 +3316,7 @@ msgstr "La page sera actualisée lorsque le téléversement sera terminé."
#: pods/templates/videos/video_edit.html:399
msgid "Important"
-msgstr ""
+msgstr "Important"
#: pods/templates/videos/video_edit.html:405
msgid "Uploading"
@@ -3374,11 +3542,19 @@ msgstr ""
"vous pouvez ajouter un mot de passe qui sera demandé à toute personne "
"souhaitant visionner votre contenu."
-#: pods/templates/videos/video_edit.html:651
+#: pods/templates/videos/video_edit.html:644
+msgid ""
+"If your video is in a playlist the password of your video will be removed "
+"automatically."
+msgstr ""
+"Si votre vidéo est dans une playlist le mot de passe de votre vidéo sera "
+"automatiquement supprimé."
+
+#: pods/templates/videos/video_edit.html:652
msgid "Keywords"
msgstr "Mots-clés"
-#: pods/templates/videos/video_edit.html:656
+#: pods/templates/videos/video_edit.html:657
msgid ""
"Please try to add only relevant keywords that can be useful to other users."
msgstr ""
@@ -3460,25 +3636,25 @@ msgstr "Les enrichissements ne peuvent se chevaucher."
msgid "You must save your enrichments to view the result."
msgstr "Vous devez sauvegarder pour visualiser le résultat."
-#: pods/templates/videos/video_interactive.html:175
+#: pods/templates/videos/video_interactive.html:173
msgid "Creation"
msgstr "Création"
-#: pods/templates/videos/video_interactive.html:196
+#: pods/templates/videos/video_interactive.html:194
msgid "Loading, please wait..."
msgstr "Chargement en cours, veuillez patienter..."
+#: pods/templates/videos/video_interactive.html:203
#: pods/templates/videos/video_interactive.html:205
-#: pods/templates/videos/video_interactive.html:207
msgid "Delete the interactive part of this video"
msgstr "Supprimer la partie interactive de cette vidéo"
+#: pods/templates/videos/video_interactive.html:207
#: pods/templates/videos/video_interactive.html:209
-#: pods/templates/videos/video_interactive.html:211
msgid "Manage scores"
msgstr "Gérer les scores"
-#: pods/templates/videos/video_interactive.html:225
+#: pods/templates/videos/video_interactive.html:223
msgid ""
"Do not forget to save your work regularly. Especially if you add an "
"interaction."
@@ -3486,7 +3662,7 @@ msgstr ""
"N'oubliez pas de sauvegarder votre travail régulièrement. Surtout si vous "
"ajoutez une interaction."
-#: pods/templates/videos/video_interactive.html:227
+#: pods/templates/videos/video_interactive.html:225
msgid ""
"To save and continue your work click on the button [Save and continue]. If "
"you have completed your work click on the button [Save and return to video] "
@@ -3497,17 +3673,17 @@ msgstr ""
"le bouton [Sauvegarder et retour à la vidéo] pour voir votre nouvelle vidéo "
"interactive."
-#: pods/templates/videos/video_interactive.html:231
-#: pods/templates/videos/video_interactive.html:232
-#: pods/templates/videos/video_interactive.html:248
-#: pods/templates/videos/video_interactive.html:249
+#: pods/templates/videos/video_interactive.html:229
+#: pods/templates/videos/video_interactive.html:230
+#: pods/templates/videos/video_interactive.html:246
+#: pods/templates/videos/video_interactive.html:247
msgid "Save and continue"
msgstr "Sauvegarder et continuer"
-#: pods/templates/videos/video_interactive.html:235
-#: pods/templates/videos/video_interactive.html:236
-#: pods/templates/videos/video_interactive.html:252
-#: pods/templates/videos/video_interactive.html:253
+#: pods/templates/videos/video_interactive.html:233
+#: pods/templates/videos/video_interactive.html:234
+#: pods/templates/videos/video_interactive.html:250
+#: pods/templates/videos/video_interactive.html:251
msgid "Save and return to video"
msgstr "Sauvegarder et retour à la vidéo"
@@ -3541,7 +3717,8 @@ msgstr "Ce contenu n'est pas en ligne (mode brouillon activé)."
msgid "This content is online (draft mode desactivated)."
msgstr "Ce contenu est en ligne (mode brouillon désactivé)."
-#: pods/templatetags/list.py:205 pods/templatetags/list.py:216
+#: pods/templatetags/list.py:210 pods/templatetags/list.py:217
+#: pods/templatetags/list.py:227
msgid "New"
msgstr "Nouveau"
@@ -3549,35 +3726,39 @@ msgstr "Nouveau"
msgid "-- sorry, no translation provided --"
msgstr "-- désolé, aucune traduction disponible --"
-#: pods/views.py:205
+#: pods/views.py:208
msgid "You cannot edit this channel."
msgstr "Vous ne pouvez pas modifier cette chaîne."
-#: pods/views.py:559 pods/views.py:1930
+#: pods/views.py:564 pods/views.py:2131 pods/views.py:2188
msgid "You cannot watch this video."
msgstr "Vous ne pouvez pas regarder cette vidéo."
-#: pods/views.py:603 pods/views.py:723
+#: pods/views.py:608 pods/views.py:774
msgid "Incorrect password"
msgstr "Mot de passe incorrect"
-#: pods/views.py:783
+#: pods/views.py:644 pods/views.py:673
+msgid "You don't have access to this playlist."
+msgstr "Vous ne pouvez pas accéder à cette playlist."
+
+#: pods/views.py:839
msgid "The video has been added to your favorites."
msgstr "La vidéo a été ajoutée à vos vidéos favorites."
-#: pods/views.py:788
+#: pods/views.py:844
msgid "The video has been removed from your favorites."
msgstr "La vidéo a été supprimée de vos vidéos favorites."
-#: pods/views.py:797 pods/views.py:871 pods/views.py:893
-msgid "You cannot acces this page."
+#: pods/views.py:853 pods/views.py:927 pods/views.py:966 pods/views.py:1080
+msgid "You cannot access this page."
msgstr "Vous ne pouvez pas accéder à cette page."
-#: pods/views.py:809
+#: pods/views.py:865
msgid "Video report confirmation"
msgstr "Confirmation de signalement de vidéo"
-#: pods/views.py:811
+#: pods/views.py:867
#, python-format
msgid ""
"\n"
@@ -3596,7 +3777,7 @@ msgstr ""
"Cordialement.\n"
"L'équipe Pod."
-#: pods/views.py:816
+#: pods/views.py:872
#, python-format
msgid ""
"
You just report the video: \"%(title)s\" with this comment: "
@@ -3607,11 +3788,11 @@ msgstr ""
" \"%(comment)s\".
Un courriel vient de nous être envoyé et votre "
"signalement enregistré.
Cordialement
L'équipe Pod
"
-#: pods/views.py:826
+#: pods/views.py:882
msgid "A video has just been reported."
msgstr "Une vidéo vient d'être signalée."
-#: pods/views.py:828
+#: pods/views.py:884
#, python-format
msgid ""
"The video intitled \"%(video_title)s\" has just been reported by "
@@ -3635,7 +3816,7 @@ msgstr ""
"%(owner_email)s>.\n"
"Vidéo mise en ligne le : %(video_date_added)s.\n"
-#: pods/views.py:842
+#: pods/views.py:898
#, python-format
msgid ""
"
The video intitled \"%(video_title)s\" has just been reported by "
@@ -3656,59 +3837,82 @@ msgstr ""
"href=\"mailto:%(owner_email)s\">%(owner_email)s>
. Vidéo mise en "
"ligne le : %(video_date_added)s."
-#: pods/views.py:862
+#: pods/views.py:918
msgid "This video has been reported."
msgstr "La vidéo a été signalée."
-#: pods/views.py:927 pods/views.py:1882
+#: pods/views.py:940
+msgid "You can not add a video with a password or in draft mode."
+msgstr ""
+"Vous ne pouvez pas ajouter une vidéo ayant un mot de passe ou en mode "
+"brouillon."
+
+#: pods/views.py:943
+msgid "The video has been added to your playlist."
+msgstr "La vidéo a été ajoutée à votre playlist."
+
+#: pods/views.py:952
+msgid "The video has been deleted from your playlist."
+msgstr "La vidéo a été supprimée de votre playlist."
+
+#: pods/views.py:1026
+msgid "The order of the playlist has changed."
+msgstr "L'ordre de la playlist a été changé."
+
+#: pods/views.py:1045
+#, python-format
+msgid "No playlists available for this user : %s"
+msgstr ""
+
+#: pods/views.py:1114 pods/views.py:2078
msgid "You cannot edit this video."
msgstr "Vous ne pouvez pas éditer cette vidéo."
-#: pods/views.py:1040 pods/views.py:1083 pods/views.py:1217 pods/views.py:1348
-#: pods/views.py:1479
+#: pods/views.py:1234 pods/views.py:1277 pods/views.py:1411 pods/views.py:1542
+#: pods/views.py:1673
msgid "You cannot complement this video."
msgstr "Vous ne pouvez pas compléter cette vidéo."
-#: pods/views.py:1141 pods/views.py:1274 pods/views.py:1407 pods/views.py:1541
+#: pods/views.py:1335 pods/views.py:1468 pods/views.py:1601 pods/views.py:1735
msgid "Please correct errors"
msgstr "Veuillez corriger les erreurs."
-#: pods/views.py:1621
+#: pods/views.py:1817
msgid "You cannot chapter this video."
msgstr "Vous ne pouvez pas chapitrer cette vidéo."
-#: pods/views.py:1673 pods/views.py:1798
+#: pods/views.py:1869 pods/views.py:1994
msgid "Please correct errors."
msgstr "Veuillez corriger les erreurs."
-#: pods/views.py:1745
+#: pods/views.py:1941
msgid "You cannot enrich this video."
msgstr "Vous ne pouvez pas enrichir cette vidéo."
-#: pods/views.py:1892
+#: pods/views.py:2088
msgid "You cannot delete this video."
msgstr "Vous ne pouvez pas supprimer cette vidéo."
-#: pods/views.py:1908
+#: pods/views.py:2109
msgid "The video has been deleted."
msgstr "La vidéo a été supprimée."
-#: pods/views.py:2176
+#: pods/views.py:2413
msgid "Mediapath should be indicated."
msgstr "MediaPath doit être indiqué."
-#: pods/views.py:2200
+#: pods/views.py:2437
msgid ""
"Your publication is saved. Adding it to your videos will be in a few minutes."
msgstr ""
"Votre publication est enregistrée. Son ajout à vos vidéos se fera dans "
"quelques minutes."
-#: pods/views.py:2257
+#: pods/views.py:2494
msgid "Recording"
msgstr "En cours d'enregistrement"
-#: pods/views.py:2259
+#: pods/views.py:2496
#, python-format
msgid ""
"Hello, \n"
@@ -3734,7 +3938,7 @@ msgstr ""
"\n"
"Cordialement"
-#: pods/views.py:2263
+#: pods/views.py:2500
#, python-format
msgid ""
"Hello,
a new mediacourse has just be added on %(title_site)s from the "
@@ -3748,6 +3952,15 @@ msgstr ""
"%(link_url)s Si le lien n'est pas actif, il faut le copier-coller "
"dans la barre d'adresse de votre navigateur.
diff --git a/pod_project/pods/templates/playlists/playlist_form.html b/pod_project/pods/templates/playlists/playlist_form.html
new file mode 100644
index 00000000..8067cd41
--- /dev/null
+++ b/pod_project/pods/templates/playlists/playlist_form.html
@@ -0,0 +1,26 @@
+{% load bootstrap3 %}
+{% load i18n %}
+
\ No newline at end of file
diff --git a/pod_project/pods/templates/playlists/playlist_list.html b/pod_project/pods/templates/playlists/playlist_list.html
new file mode 100644
index 00000000..fa544edc
--- /dev/null
+++ b/pod_project/pods/templates/playlists/playlist_list.html
@@ -0,0 +1,47 @@
+{% comment %}
+Copyright (C) 2014 Nicolas Can
+Ce programme est un logiciel libre : vous pouvez
+le redistribuer et/ou le modifier sous les termes
+de la licence GNU Public Licence telle que publiée
+par la Free Software Foundation, soit dans la
+version 3 de la licence, ou (selon votre choix)
+toute version ultérieure.
+Ce programme est distribué avec l'espoir
+qu'il sera utile, mais SANS AUCUNE
+GARANTIE : sans même les garanties
+implicites de VALEUR MARCHANDE ou
+D'APPLICABILITÉ À UN BUT PRÉCIS. Voir
+la licence GNU General Public License
+pour plus de détails.
+Vous devriez avoir reçu une copie de la licence
+GNU General Public Licence
+avec ce programme. Si ce n'est pas le cas,
+voir http://www.gnu.org/licenses/
+{% endcomment %}
+{% load i18n list staticfiles %}
+{% load thumbnail %}
+
+
+ {% for playlist in playlists %}
+ {% if playlist.get_videos.count > 0 %}
+