1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 01:39:24 +02:00

Fix offline video

This commit is contained in:
DanieL 2022-07-18 17:34:43 -03:00
parent 0206094cc4
commit 54125cc523
21 changed files with 223 additions and 1356 deletions

1
.gitignore vendored
View file

@ -79,3 +79,4 @@ sitemap.xml
/.project
objects/ezyang/
/plugin/Conspyre/
/plugin/VideoOffline/

View file

@ -38,8 +38,13 @@ function __($str, $allowHTML = false) {
return str_replace(array("'", '"', "<", '>'), array('&apos;', '&quot;', '&lt;', '&gt;'), $return);
}
function printJSString($str) {
echo json_encode(__($str));
function printJSString($str, $return = false) {
$text = json_encode(__($str));
if($return){
return $text;
}else{
echo $text;
}
}
function isRTL() {

View file

@ -2455,7 +2455,8 @@ function createWebPIfNotExists($path){
return $nextGenPath;
}
function getVideoImagewithHoverAnimation($relativePath, $relativePathHoverAnimation='', $title='', $id=''){
function getVideoImagewithHoverAnimation($relativePath, $relativePathHoverAnimation='', $title=''){
$id = uniqid();
$img = getImageTagIfExists($relativePath, $title, "thumbsJPG{$id}", '', 'thumbsJPG img img-responsive').PHP_EOL;
if(!empty($relativePathHoverAnimation) && empty($_REQUEST['noImgGif'])){
$img .= getImageTagIfExists($relativePathHoverAnimation, $title, "thumbsGIF{$id}", 'position: absolute; top: 0;', 'thumbsGIF img img-responsive ', true).PHP_EOL;
@ -3824,14 +3825,14 @@ function getItemprop($videos_id) {
if ($duration == "PT0H0M0S") {
$duration = "PT0H0M1S";
}
$output = '<span itemprop="name" content="' . getSEOTitle($video['title']) . '" />
<span itemprop="description" content="' . $description . '" />
<span itemprop="thumbnailUrl" content="' . $img . '" />
<span itemprop="uploadDate" content="' . date("Y-m-d\Th:i:s", strtotime($video['created'])) . '" />
<span itemprop="duration" content="' . $duration . '" />
<span itemprop="contentUrl" content="' . Video::getLinkToVideo($videos_id) . '" />
<span itemprop="embedUrl" content="' . parseVideos(Video::getLinkToVideo($videos_id)) . '" />
<span itemprop="interactionCount" content="' . $video['views_count'] . '" />';
$output = '<span itemprop="name" content="' . getSEOTitle($video['title']) . '"></span>
<span itemprop="description" content="' . $description . '"></span>
<span itemprop="thumbnailUrl" content="' . $img . '"></span>
<span itemprop="uploadDate" content="' . date("Y-m-d\Th:i:s", strtotime($video['created'])) . '"></span>
<span itemprop="duration" content="' . $duration . '"></span>
<span itemprop="contentUrl" content="' . Video::getLinkToVideo($videos_id) . '"></span>
<span itemprop="embedUrl" content="' . parseVideos(Video::getLinkToVideo($videos_id)) . '"></span>
<span itemprop="interactionCount" content="' . $video['views_count'] . '"></span>';
ObjectYPT::setCache("getItemprop{$videos_id}", $output);
echo $output;

View file

@ -206,117 +206,9 @@ function createGallerySection($videos, $crc = "", $get = array(), $ignoreAds = f
}
?>
<div class=" <?php echo $colsClass; ?> galleryVideo fixPadding" style="z-index: <?php echo $zindex--; ?>; min-height: 175px;">
<a class="galleryLink <?php echo $isserieClass; ?>" videos_id="<?php echo $value['id']; ?>"
href="<?php echo $href; ?>"
embed="<?php echo $embed; ?>"
alternativeLink="<?php echo @$value['alternativeLink']; ?>"
title="<?php echo htmlentities($value['title']); ?>">
<?php
@$timesG[__LINE__] += microtime(true) - $startG;
$startG = microtime(true);
if (empty($value['images'])) {
$images = Video::getImageFromFilename($value['filename'], $value['type']);
@$timesG[__LINE__] += microtime(true) - $startG;
if (!is_object($images)) {
$images = new stdClass();
$images->thumbsGif = "";
$images->poster = "" . getCDN() . "view/img/notfound.jpg";
$images->thumbsJpg = "" . getCDN() . "view/img/notfoundThumbs.jpg";
$images->thumbsJpgSmall = "" . getCDN() . "view/img/notfoundThumbsSmall.jpg";
}
if ($value['type'] === 'serie' && !empty($value['serie_playlists_id']) && stripos($images->thumbsJpg, 'notfound') !== false) {
$images = PlayList::getRandomImageFromPlayList($value['serie_playlists_id']);
}
} else {
$images = (Object) $value['images'];
}
$startG = microtime(true);
$imgGif = $images->thumbsGif;
$poster = $images->thumbsJpg;
?>
<div class="aspectRatio16_9">
<?php
$relativePathHoverAnimation = '';
if (!empty($imgGif) && empty($_REQUEST['noImgGif'])) {
$relativePathHoverAnimation = $imgGif;
}
echo getVideoImagewithHoverAnimation($images->poster, $relativePathHoverAnimation, $value['title'], $value['id']);
//var_dump($images);
//exit;
echo AVideoPlugin::thumbsOverlay($value['id']);
@$timesG[__LINE__] += microtime(true) - $startG;
$startG = microtime(true);
if ($galeryDetails) {
if (!empty($program) && $isserie) {
?>
<div class="gallerySerieOverlay">
<div class="gallerySerieOverlayTotal">
<?php
$plids = PlayList::getVideosIDFromPlaylistLight($value['serie_playlists_id']);
echo count($plids);
?>
<br><i class="fas fa-list"></i>
</div>
<i class="fas fa-play"></i>
<?php
echo __("Play All");
?>
</div>
<?php
} else
if (!empty($program) && User::isLogged()) {
?>
<div class="galleryVideoButtons">
<?php
//var_dump($value['isWatchLater'], $value['isFavorite']);
if ($value['isWatchLater']) {
$watchLaterBtnAddedStyle = "";
$watchLaterBtnStyle = "display: none;";
} else {
$watchLaterBtnAddedStyle = "display: none;";
$watchLaterBtnStyle = "";
}
if ($value['isFavorite']) {
$favoriteBtnAddedStyle = "";
$favoriteBtnStyle = "display: none;";
} else {
$favoriteBtnAddedStyle = "display: none;";
$favoriteBtnStyle = "";
}
?>
<button onclick="addVideoToPlayList(<?php echo $value['id']; ?>, false, <?php echo $value['watchLaterId']; ?>);return false;" class="btn btn-dark btn-xs watchLaterBtnAdded watchLaterBtnAdded<?php echo $value['id']; ?>" data-toggle="tooltip" data-placement="left" title="<?php echo __("Added On Watch Later"); ?>" style="color: #4285f4;<?php echo $watchLaterBtnAddedStyle; ?>" ><i class="fas fa-check"></i></button>
<button onclick="addVideoToPlayList(<?php echo $value['id']; ?>, true, <?php echo $value['watchLaterId']; ?>);return false;" class="btn btn-dark btn-xs watchLaterBtn watchLaterBtn<?php echo $value['id']; ?>" data-toggle="tooltip" data-placement="left" title="<?php echo __("Watch Later"); ?>" style="<?php echo $watchLaterBtnStyle; ?>" ><i class="fas fa-clock"></i></button>
<br>
<button onclick="addVideoToPlayList(<?php echo $value['id']; ?>, false, <?php echo $value['favoriteId']; ?>);return false;" class="btn btn-dark btn-xs favoriteBtnAdded favoriteBtnAdded<?php echo $value['id']; ?>" data-toggle="tooltip" data-placement="left" title="<?php echo __("Added On Favorite"); ?>" style="color: #4285f4; <?php echo $favoriteBtnAddedStyle; ?>"><i class="fas fa-check"></i></button>
<button onclick="addVideoToPlayList(<?php echo $value['id']; ?>, true, <?php echo $value['favoriteId']; ?>);return false;" class="btn btn-dark btn-xs favoriteBtn favoriteBtn<?php echo $value['id']; ?> faa-parent animated-hover" data-toggle="tooltip" data-placement="left" title="<?php echo __("Favorite"); ?>" style="<?php echo $favoriteBtnStyle; ?>" ><i class="fas fa-heart faa-pulse faa-fast" ></i></button>
</div>
<?php
}
}
?>
</div>
<?php
if (isToShowDuration($value['type'])) {
?>
<span class="duration"><?php echo Video::getCleanDuration($value['duration']); ?></span>
<div class="progress" style="height: 3px; margin-bottom: 2px;">
<div class="progress-bar progress-bar-danger" role="progressbar" style="width: <?php echo $value['progress']['percent'] ?>%;" aria-valuenow="<?php echo $value['progress']['percent'] ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<?php
}
?>
</a>
<a class="h6 galleryLink <?php echo $isserieClass; ?>" videos_id="<?php echo $value['id']; ?>"
href="<?php echo $href; ?>"
embed="<?php echo $embed; ?>"
alternativeLink="<?php echo @$value['alternativeLink']; ?>"
title="<?php echo htmlentities(getSEOTitle($value['title'], 200)); ?>">
<strong class="title"><?php echo getSEOTitle($value['title']); ?></strong>
</a>
<?php
echo Video::getVideoImagewithHoverAnimationFromVideosId($value['id'], true, true, true);
?>
<?php
if ($galeryDetails) {
?>
@ -548,7 +440,7 @@ function createGalleryLiveSection($videos) {
<div class="aspectRatio16_9">
<?php
$relativePathHoverAnimation = @$video['imgGif'];
echo getVideoImagewithHoverAnimation($video['poster'], $relativePathHoverAnimation, $video['title'], $video['id']);
echo getVideoImagewithHoverAnimation($video['poster'], $relativePathHoverAnimation, $video['title']);
echo $liveNow;
?>
</div>

View file

@ -1,19 +1,8 @@
.gallery .duration {
position: absolute;
background: rgba(0, 0, 0, 0.6)!important;
padding: 3px;
color: #FFF;
top: 5px;
left: 25px;
font-size: 0.9em;
border-radius: 5px;
}
.gallery .title,
.videosDetails .title {
font-size: 1em;
margin: 0;
padding: 5px 0 0 0;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
@ -169,7 +158,8 @@ a.h6{
justify-content: center;
width: 24px;
}
.galleryVideo:hover .galleryVideoButtons{
.galleryVideo:hover .galleryVideoButtons,
.thumbsImageContainer:hover .galleryVideoButtons {
display: block !important;
}
.galleryVideo .galleryVideoButtons button:hover{

View file

@ -78,84 +78,28 @@ if ($obj->BigVideo && empty($_GET['showOnly'])) {
<div class="item <?php echo $count === 1 ? "active" : ""; ?>">
<div class="clear clearfix">
<div class="row thumbsImage">
<div class="<?php echo $colClass1; ?> galleryVideo">
<a class="galleryLink <?php echo $isserieClass; ?>" videos_id="<?php echo $videoRow['id']; ?>"
href="<?php echo Video::getLink($videoRow['id'], $videoRow['clean_title'], false, $get); ?>"
embed="<?php echo Video::getLink($videoRow['id'], $videoRow['clean_title'], true, $get); ?>"
title="<?php echo $videoRow['title']; ?>" style="">
<?php
$images = Video::getImageFromFilename($videoRow['filename'], $videoRow['type']);
$imgGif = $images->thumbsGif;
$poster = isMobile() ? $images->thumbsJpg : $images->poster;
?>
<div class="aspectRatio16_9">
<div class="<?php echo $colClass1; ?>">
<?php
echo Video::getVideoImagewithHoverAnimationFromVideosId($videoRow['id']);
?>
<?php
if (!empty($program) && $videoRow['type'] == 'serie' && !empty($videoRow['serie_playlists_id'])) {
?>
<div class="gallerySerieOverlay">
<div class="gallerySerieOverlayTotal">
<?php
$plids = PlayList::getVideosIDFromPlaylistLight($videoRow['serie_playlists_id']);
echo count($plids);
?>
<br><i class="fas fa-list"></i>
</div>
<i class="fas fa-play"></i>
<?php
$relativePathHoverAnimation = '';
if (!empty($obj->GifOnBigVideo) && !empty($imgGif)) {
$relativePathHoverAnimation = $imgGif;
}
echo getVideoImagewithHoverAnimation($poster, $relativePathHoverAnimation, $videoRow['title'], $videoRow['id']);
echo __("Play All");
?>
</div>
<?php
if (isToShowDuration($videoRow['type'])) {
?>
<span class="duration"><?php echo Video::getCleanDuration($videoRow['duration']); ?></span>
<div class="progress" style="height: 3px; margin-bottom: 2px;">
<div class="progress-bar progress-bar-danger" role="progressbar" style="width: <?php echo $videoRow['progress']['percent'] ?>%;" aria-valuenow="<?php echo $videoRow['progress']['percent'] ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<?php
}
if (!empty($program) && $videoRow['type'] == 'serie' && !empty($videoRow['serie_playlists_id'])) {
?>
<div class="gallerySerieOverlay">
<div class="gallerySerieOverlayTotal">
<?php
$plids = PlayList::getVideosIDFromPlaylistLight($videoRow['serie_playlists_id']);
echo count($plids);
?>
<br><i class="fas fa-list"></i>
</div>
<i class="fas fa-play"></i>
<?php
echo __("Play All");
?>
</div>
<?php
} else
if (User::isLogged() && !empty($program)) {
?>
<div class="galleryVideoButtons" style="margin-right: 20px;">
<?php
//var_dump($value['isWatchLater'], $value['isFavorite']);
if ($videoRow['isWatchLater']) {
$watchLaterBtnAddedStyle = "";
$watchLaterBtnStyle = "display: none;";
} else {
$watchLaterBtnAddedStyle = "display: none;";
$watchLaterBtnStyle = "";
}
if ($videoRow['isFavorite']) {
$favoriteBtnAddedStyle = "";
$favoriteBtnStyle = "display: none;";
} else {
$favoriteBtnAddedStyle = "display: none;";
$favoriteBtnStyle = "";
}
?>
<button onclick="addVideoToPlayList(<?php echo $videoRow['id']; ?>, false, <?php echo $videoRow['watchLaterId']; ?>);return false;" class="btn btn-dark btn-xs watchLaterBtnAdded watchLaterBtnAdded<?php echo $videoRow['id']; ?>" title="<?php echo __("Added On Watch Later"); ?>" style="color: #4285f4;<?php echo $watchLaterBtnAddedStyle; ?>" ><i class="fas fa-check"></i></button>
<button onclick="addVideoToPlayList(<?php echo $videoRow['id']; ?>, true, <?php echo $videoRow['watchLaterId']; ?>);return false;" class="btn btn-dark btn-xs watchLaterBtn watchLaterBtn<?php echo $videoRow['id']; ?>" title="<?php echo __("Watch Later"); ?>" style="<?php echo $watchLaterBtnStyle; ?>" ><i class="fas fa-clock"></i></button>
<br>
<button onclick="addVideoToPlayList(<?php echo $videoRow['id']; ?>, false, <?php echo $videoRow['favoriteId']; ?>);return false;" class="btn btn-dark btn-xs favoriteBtnAdded favoriteBtnAdded<?php echo $videoRow['id']; ?>" title="<?php echo __("Added On Favorite"); ?>" style="color: #4285f4; <?php echo $favoriteBtnAddedStyle; ?>"><i class="fas fa-check"></i></button>
<button onclick="addVideoToPlayList(<?php echo $videoRow['id']; ?>, true, <?php echo $videoRow['favoriteId']; ?>);return false;" class="btn btn-dark btn-xs favoriteBtn favoriteBtn<?php echo $videoRow['id']; ?> faa-parent animated-hover" title="<?php echo __("Favorite"); ?>" style="<?php echo $favoriteBtnStyle; ?>" ><i class="fas fa-heart faa-pulse faa-fast" ></i></button>
</div>
<?php
}
?>
</a>
<?php }
?>
</div>
<div class="<?php echo $colClass2; ?>">
<div class="<?php echo $colClass3; ?>">
@ -180,8 +124,8 @@ if ($obj->BigVideo && empty($_GET['showOnly'])) {
</div>
<div class="galeryDetails">
<div class="galleryTags">
<?php
if (empty($_GET['catName']) && !empty($obj->showCategoryTag)) {
<?php
if (empty($_GET['catName']) && !empty($obj->showCategoryTag)) {
?>
<a class="label label-default" href="<?php echo "{$global['webSiteRootURL']}cat/{$videoRow['clean_category']}"; ?>" data-toggle="tooltip" title="<?php echo $videoRow['category']; ?>">
<?php
@ -236,7 +180,7 @@ if ($obj->BigVideo && empty($_GET['showOnly'])) {
</div>
<?php if (Video::canEdit($videoRow['id'])) { ?>
<div>
<a href="#" onclick="avideoModalIframe(webSiteRootURL+'view/managerVideosLight.php?avideoIframe=1&videos_id=<?php echo $videoRow['id']; ?>');return false;"><i class="fa fa-edit"></i> <?php echo __("Edit Video"); ?></a>
<a href="#" onclick="avideoModalIframe(webSiteRootURL + 'view/managerVideosLight.php?avideoIframe=1&videos_id=<?php echo $videoRow['id']; ?>');return false;"><i class="fa fa-edit"></i> <?php echo __("Edit Video"); ?></a>
</div>
<?php } ?>
<?php if (!empty($videoRow['trailer1'])) { ?>

View file

@ -54,7 +54,6 @@ class PlayerSkins extends PluginAbstract {
$obj->showLogoAdjustLeft = "-74px";
$obj->showLogoAdjustTop = "-22px;";
$obj->disableEmbedTopInfo = false;
$obj->disableOfflineVideos = false;
$obj->contextMenuDisableEmbedOnly = false;
$obj->contextMenuLoop = true;
$obj->contextMenuCopyVideoURL = true;
@ -264,9 +263,6 @@ class PlayerSkins extends PluginAbstract {
if ($obj->showShareAutoplay && isVideoPlayerHasProgressBar() && empty($obj->forceAlwaysAutoplay) && empty($_REQUEST['hideAutoplaySwitch'])) {
$css .= "<link href=\"" . getURL('plugin/PlayerSkins/autoplayButton.css') . "\" rel=\"stylesheet\" type=\"text/css\"/>";
}
if (self::showOfflineVideo()) {
$css .= "<link href=\"" . getURL('plugin/PlayerSkins/offlineButton.css') . "\" rel=\"stylesheet\" type=\"text/css\"/>";
}
}
$url = urlencode(getSelfURI());
@ -319,9 +315,6 @@ class PlayerSkins extends PluginAbstract {
$js .= "<!-- PlayerSkins empty(\$_REQUEST['hideAutoplaySwitch']) -->";
}
}
if (self::showOfflineVideo()) {
PlayerSkins::getStartPlayerJS(file_get_contents("{$global['systemRootPath']}plugin/PlayerSkins/offlineButton.js"));
}
}
if (isAudio()) {
$videos_id = getVideos_id();
@ -338,22 +331,7 @@ class PlayerSkins extends PluginAbstract {
}
include $global['systemRootPath'] . 'plugin/PlayerSkins/mediaSession.php';
PlayerSkins::addOnPlayerReady('if(typeof updateMediaSessionMetadata === "function"){updateMediaSessionMetadata();}');
if (isVideo()) {
$js .= "<script src=\"" . getURL('node_modules/pouchdb/dist/pouchdb.min.js') . "\"></script>";
if (self::showOfflineVideo()) {
$detect = new Mobile_Detect();
if ($detect->isiOS()) {
$js .= "<script>var offline_iOSVersion = ".json_encode($detect->version('iOS', Mobile_Detect::VERSION_TYPE_FLOAT)).";</script>";
} else{
$js .= "<script>var offline_iOSVersion = 0;</script>";
}
//var_dump($detect->isiOS(), $detect->version('iOS'));exit;
$js .= "<script>const offlineVideoDbName = 'videos_offlineDb_" . User::getId() . "';</script>";
$js .= "<script src=\"" . getURL('plugin/PlayerSkins/offlineVideo.js') . "\"></script>";
}
}
PlayerSkins::addOnPlayerReady('if(typeof updateMediaSessionMetadata === "function"){updateMediaSessionMetadata();}');
return $js;
}
@ -700,26 +678,6 @@ class PlayerSkins extends PluginAbstract {
}
return array($tags);
}
public static function showOfflineVideo() {
global $global;
$obj = AVideoPlugin::getDataObject('PlayerSkins');
if (!empty($obj->disableOfflineVideos)) {
return false;
}
if (empty($global['developer_mode'])) {
return false;
}
$videos_id = getVideos_id();
if (empty($videos_id)) {
return false;
}
$types = Video::getVideoTypeFromId($videos_id);
//var_dump($types);exit;
return !empty($types->mp4) || !empty($types->m3u8);
}
}

View file

@ -1,27 +0,0 @@
.offline-button{
outline: none;
}
.offline-button:before {
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
content: "\f358";
font-size: 1.2em;
line-height: 1.0em;
font-family: "Font Awesome\ 5 Free";
font-weight: 400;
}
.offline-button.hasOfflineVideo:before {
content: "\f058";
font-weight: 400;
}
.offline-button.loading:before {
content: "\f110";
font-weight: 900;
}
.playingOfflineVideo .offline-button.hasOfflineVideo:before {
content: "\f13a";
font-weight: 900;
color: yellow;
}

View file

@ -1,25 +0,0 @@
var Button = videojs.getComponent('Button');
var offlineButton = videojs.extend(Button, {
//constructor: function(player, options) {
constructor: function () {
Button.apply(this, arguments);
this.addClass('offline-button');
this.controlText("offline");
},
handleClick: function () {
console.log('offlineButton clicked');
openDownloadOfflineVideoPage();
}
});
videojs.registerComponent('offlineButton', offlineButton);
player.getChild('controlBar').addChild('offlineButton', {}, getPlayerButtonIndex('fullscreenToggle') - 1);
player.on('resolutionchange', function (event) {
if(isOfflineSourceSelectedToPlay()){
setOfflineButton('playingOffline', false);
}else{
setOfflineButton('readyToPlayOffline', false);
}
});

View file

@ -1,7 +0,0 @@
.offlinevideos .isDownloading .btn,
.offlinevideos .isDeleting .btn,
.offlinevideos div.panel-success > div.panel-heading > button.btn.btn-warning,
.offlinevideos div.panel-default > div.panel-heading > button.btn.btn-danger,
.offlinevideos div.panel-default > div.panel-heading > button.btn.btn-success{
display: none;
}

View file

@ -1,543 +0,0 @@
function replaceVideoSourcesPerOfflineVersion() {
if (!empty(mediaId)) {
replaceVideoSourcesPerOfflineVersionFromVideosId(mediaId);
} else {
console.error("replaceVideoSourcesPerOfflineVersion: empty mediaId");
}
}
async function replaceVideoSourcesPerOfflineVersionFromVideosId(videos_id) {
videos_id = parseInt(videos_id);
if (empty(videos_id)) {
//console.error("replaceVideoSourcesPerOfflineVersionFromVideosId: empty videos id");
return false;
}
if (!$("#mainVideo").length) {
//console.error("replaceVideoSourcesPerOfflineVersionFromVideosId: mainVideo not present");
return false;
}
//videoJSRecreateSources(false);
$('source.offline-video').remove();
getAllOfflineVideoPouch(videos_id).then(async function (collection) {
//console.log("replaceVideoSourcesPerOfflineVersionFromVideosId: ",videos_id, collection);
var sources = [];
for (var i in collection.rows) {
var video = collection.rows[i].doc;
if (typeof video !== 'object') {
continue;
}
for (var i in video._attachments) {
if (i == 'poster') {
continue;
}
//console.log("replaceVideoSourcesPerOfflineVersionFromVideosId video: ",video);
var fileBlob = await offlineVideoDBPouch.getAttachment(video._id, i);
var source = createSourceFromBlob(fileBlob, video.video_type, i);
console.log("replaceVideoSourcesPerOfflineVersionFromVideosId video: ", video, source);
createSourceElement(source);
sources.push(source);
}
}
console.log("replaceVideoSourcesPerOfflineVersionFromVideosId sources: ", sources);
player.src(sources);
videoJSRecreateSources(sources[0]);
offlineVideoButtonCheck();
}).catch(function (e) {
console.log("replaceVideoSourcesPerOfflineVersionIfExists: Error: " + (e.stack || e));
});
}
async function updateAllOfflineVideoMetaData() {
var result = await getAllOfflineVideoPouch(0).then(async function (videoRow) {
console.log('updateAllOfflineVideoMetaData videoRow', videoRow);
var videosUpdated = [];
for (var i in videoRow.rows) {
var video = videoRow.rows[i].doc;
if (typeof video !== 'object') {
continue;
}
videosUpdated.push(await updateOfflineVideoMetaData(video.videos_id));
}
return videosUpdated;
}).catch(function (err) {
console.log('updateAllOfflineVideoMetaData videoRow error', err);
return err;
});
return result;
}
async function updateOfflineVideoMetaData(videos_id) {
videos_id = parseInt(videos_id);
if (empty(videos_id)) {
//console.error("replaceVideoSourcesPerOfflineVersionFromVideosId: empty videos id");
return false;
}
var apiURL = webSiteRootURL + 'plugin/API/get.json.php?APIName=video&videos_id=' + videos_id;
$.ajax({
url: apiURL,
success: async function (response) {
if (response.error) {
avideoAlertError(response.message);
return false;
}
if (empty(response.response.rows)) {
avideoToastError('Empty respose');
return false;
}
var row = response.response.rows[0];
var result = await getAllOfflineVideoPouch(videos_id).then(async function (videoRow) {
//console.log('updateOfflineVideoMetaData videoRow', videoRow);
var videosUpdated = [];
for (var i in videoRow.rows) {
var video = videoRow.rows[i].doc;
if (typeof video !== 'object') {
continue;
}
//video = video.doc;
video.title = row.title;
video.duration = row.duration;
video.link = row.link;
video.duration_in_seconds = row.duration_in_seconds;
video.modified = new Date().getTime();
video.meta_data_modified = video.modified;
console.log('updateOfflineVideoMetaData video', video);
videosUpdated.push(await offlineVideoDBPouch.put(video).then(async function (result) {
fetch(row.images.poster).then(res => res.blob()).then(async function (fileBlob) {
//console.log('updateOfflineVideoMetaData fetched put', result, fileBlob);
var result2 = await offlineVideoDBPouch.putAttachment(result.id, 'poster', result.rev, fileBlob, 'image/jpeg').then(function (result2) {
// handle result
//console.log('updateOfflineVideoMetaData fetched ', result2);
//avideoToastSuccess('Meta data updated');
return result2;
}).catch(function (err) {
//console.log('updateOfflineVideoMetaData fetched ', err);
avideoToastError('Meta data Attachment: ' + err.message);
return err;
});
return result2;
});
}).catch(function (err) {
//console.log('storeOfflineVideoPouch put error', err);
avideoToastError('Video Info: ' + err.message);
return err;
}));
}
return videosUpdated;
}).catch(function (err) {
console.log('getOfflineVideoPouch videoRow error', err);
avideoToastError('Model creation error: ' + err.message);
return err;
});
return result;
}
});
}
function createSourceFromBlob(blob, type, res) {
if (empty(type)) {
type = 'video/mp4';
}
if (empty(res)) {
res = 'auto';
}
blob = blob.slice(0, blob.size, type);
var src;
if (window.webkitURL != null) {
src = window.webkitURL.createObjectURL(blob);
} else {
src = window.URL.createObjectURL(blob);
}
var source = {
src: src,
type: type,
res: res,
class: 'offline-video',
label: res + 'p <span class="label label-warning" style="padding: 0 2px; font-size: .8em; display: inline;">(OFFLINE)</span>',
};
console.log('createSourceFromBlob ', source, blob);
return source;
}
function createImageSourceFromBlob(blob, type) {
if (empty(type)) {
type = 'image/jpeg';
}
blob = blob.slice(0, blob.size, type);
var src;
if (window.webkitURL != null) {
src = window.webkitURL.createObjectURL(blob);
} else {
src = window.URL.createObjectURL(blob);
}
var source = {
src: src,
type: type,
};
console.log('createImageSourceFromBlob ', source, blob);
return source;
}
function getOneOfflineVideoSource() {
var first = false;
var video480 = false;
$("#mainVideo source").each(function (index) {
if (empty(first)) {
first = $(this);
}
var resolution = $(this).attr("res");
if (resolution == 480) {
video480 = $(this);
}
});
if (!empty(video480)) {
console.log('getOneOfflineVideoSource 480p video found', video480);
return video480;
}
console.log('getOneOfflineVideoSource first video found', first);
return first;
}
function changeProgressBarOfflineVideo(progressBarSelector, value) {
value = value.toFixed(2);
$(progressBarSelector).find('.progress-bar')
.attr('aria-valuenow', value)
.css('width', value + '%')
.text(value + '%');
}
async function fetchVideoFromNetwork(src, type, resolution, progressBarSelector) {
if (src.match(/\.m3u8/) && typeof fetchVideoFromNetworkHLS === 'function') {
return await fetchVideoFromNetworkHLS(src, type, resolution, progressBarSelector);
} else {
return await fetchVideoFromNetworkMP4(src, type, resolution, progressBarSelector);
}
}
async function fetchVideoFromNetworkMP4(src, type, resolution, progressBarSelector) {
console.log('fetching videos from network', src, type, resolution, progressBarSelector);
// Step 1: start the fetch and obtain a reader
let response = await fetch(src);
const reader = response.body.getReader();
// Step 2: get total length
const contentLength = +response.headers.get('Content-Length');
// Step 3: read the data
let receivedLength = 0; // received that many bytes at the moment
let chunks = []; // array of received binary chunks (comprises the body)
while (true) {
const {done, value} = await reader.read();
if (done) {
break;
}
chunks.push(value);
receivedLength += value.length;
var percentageComplete = (receivedLength / contentLength) * 100;
var percentageCompleteStr = percentageComplete.toFixed(2) + '%';
if (!empty(progressBarSelector)) {
changeProgressBarOfflineVideo(progressBarSelector, percentageComplete);
}
console.log(`Received ${receivedLength} of ${contentLength} ${percentageCompleteStr}`);
}
let fileBlob = new Blob(chunks, {type: type});
console.log('fetching videos from network finish', type, fileBlob);
return await storeOfflineVideoPouch(src, fileBlob, type, mediaId, resolution);
}
async function storeOfflineVideoPouch(src, fileBlob, type, videos_id, resolution) {
var result = await getOfflineVideoPouch(videos_id).then(async function (videoRow) {
console.log('getOfflineVideoPouch videoRow', videoRow);
videoRow._id = getDBOfflineID(videos_id);
videoRow.src = src;
videoRow.video_type = type;
videoRow.videos_id = videos_id;
videoRow.modified = new Date().getTime();
var result = await offlineVideoDBPouch.put(videoRow).then(async function (result) {
console.log('storeOfflineVideoPouch put', result, result.id, resolution, result._rev, fileBlob, type);
var result2 = await offlineVideoDBPouch.putAttachment(result.id, resolution, result.rev, fileBlob, type).then(function (result2) {
// handle result
console.log('offlineVideoDBPouch putAttachment', result2);
avideoToastSuccess('Video saved');
updateOfflineVideoMetaData(videos_id);
return result2;
}).catch(function (err) {
console.log('offlineVideoDBPouch putAttachment', err);
avideoToastError('Attachment: ' + err.message);
return err;
});
return result2;
}).catch(function (err) {
console.log('storeOfflineVideoPouch put error', err);
avideoToastError('Video Info: ' + err.message);
return err;
});
return result;
}).catch(function (err) {
console.log('getOfflineVideoPouch videoRow error', err);
avideoToastError('Model creation error: ' + err.message);
return err;
});
return result;
}
function getDBOfflineID(videos_id) {
return 'videos_id_' + videos_id;
}
async function getOfflineVideoPouch(videos_id) {
var result = await offlineVideoDBPouch.get(getDBOfflineID(videos_id)).catch(function (err) {
//console.log('getOfflineVideoPouch got something ', err);
if (err.name === 'not_found') {
var videoRow = {
_id: getDBOfflineID(videos_id),
src: '',
//fileBlob: fileBlob,
video_type: '',
contentLength: 0,
videos_id: videos_id,
resolution: 0,
created: new Date().getTime(),
modified: new Date().getTime(),
view: {
by_videos_id: {
map: function (doc) {
emit(doc.videos_id);
}.toString()
}
}
};
return videoRow;
} else { // hm, some other error
console.log('getOfflineVideoPouch got error ', err);
throw err;
}
}).then(function (videoRow) {
// sweet, here is our configDoc
//console.log('getOfflineVideoPouch got something row ', videoRow);
return videoRow;
}).catch(function (err) {
// handle any errors
console.log('getOfflineVideoPouch got something ', err);
throw err;
});
return result;
}
async function getAllOfflineVideoPouch(videos_id) {
videos_id = parseInt(videos_id);
var options = {include_docs: true};
if (!empty(videos_id)) {
options = {key: videos_id, include_docs: true};
}
var result = offlineVideoDBPouch.query(mapOfflineVideosId, options).then(function (result) {
// handle result
//console.log(result);
return result;
}).catch(function (err) {
// handle errors
console.log(err);
throw err;
});
return result;
}
async function deleteOfflineVideoPouch(videos_id, resolution) {
videos_id = parseInt(videos_id);
offlineVideoDBPouch.get(getDBOfflineID(videos_id)).then(function (doc) {
if (empty(resolution)) {
return offlineVideoDBPouch.remove(doc._id, doc._rev);
} else {
return offlineVideoDBPouch.removeAttachment(doc._id, resolution, doc._rev).then(function (result) {
// handle result
console.log('removeAttachment', result);
return result;
}).catch(function (err) {
console.log('removeAttachment error', err);
});
}
});
}
function createSourceElement(source) {
if (typeof source !== 'object') {
return false;
}
var sourceElement = $('<source />', source);
if (!empty(source.class)) {
$(sourceElement).addClass(source.class);
}
//createTestVideo(sourceElement.clone());
//console.log('displayVideo', source);
$("video#mainVideo, #mainVideo_html5_api").append(sourceElement);
}
function recreateFromSourceTags() {
var sources = [];
$("#mainVideo source").each(function (index) {
var res = $(this).attr("res");
var src = $(this).attr("src");
var type = $(this).attr("type");
var source = {
src: src,
type: type,
res: 480
};
sources.push(source);
});
console.log('recreateFromSourceTags', sources);
player.src(sources);
videoJSRecreateSources(0);
}
function openDownloadOfflineVideoPage() {
if (empty(mediaId)) {
return false;
}
var url = webSiteRootURL + 'plugin/PlayerSkins/offlineVideo.php';
url = addQueryStringParameter(url, 'videos_id', mediaId);
url = addQueryStringParameter(url, 'socketResourceId', socketResourceId);
avideoModalIframeSmall(url);
return true;
}
var offlineVideoButtonCheckTimeout;
var offlineVideoButtonCheckIsActive = false;
function offlineVideoButtonCheck() {
if (offlineVideoButtonCheckIsActive || empty(mediaId)) {
return false;
}
offlineVideoButtonCheckIsActive = true;
getAllOfflineVideoPouch(mediaId).then(function (collection) {
if (!empty(collection.total_rows)) {
if (isOfflineSourceSelectedToPlay()) {
setOfflineButton('playingOffline', false);
} else {
setOfflineButton('readyToPlayOffline', false);
}
} else {
setOfflineButton('download', false);
}
clearTimeout(offlineVideoButtonCheckTimeout);
offlineVideoButtonCheckTimeout = setTimeout(function () {
offlineVideoButtonCheck();
}, 5000);
offlineVideoButtonCheckIsActive = false;
}).catch(function (e) {
console.log("Error offlineVideoButtonCheck 2: ", e);
offlineVideoButtonCheckIsActive = false;
});
}
function isOfflineSourceSelectedToPlay() {
var currSource = player.currentSrc();
//console.log("isOfflineSourceSelectedToPlay: ", currSource);
if (currSource.match(/^blob:http/i)) {
return true;
} else {
return false;
}
}
function setOfflineButton(type, showLoading) {
if (showLoading) {
offlineVideoLoading(true);
}
$('#mainVideo').addClass('vjs-has-started');
switch (type) {
case 'download':
avideoTooltip(".offline-button", "Download");
$('.offline-button').removeClass('hasOfflineVideo');
$('body').removeClass('playingOfflineVideo');
offlineVideoButtonCheck();
break;
case 'readyToPlayOffline':
avideoTooltip(".offline-button", "Ready to play offline");
$('body').removeClass('playingOfflineVideo');
$('.offline-button').addClass('hasOfflineVideo');
break;
case 'playingOffline':
avideoTooltip(".offline-button", "Playing offline");
$('body').addClass('playingOfflineVideo');
$('.offline-button').addClass('hasOfflineVideo');
break;
}
if (showLoading) {
offlineVideoLoading(false);
}
}
function offlineVideoLoading(active) {
if (active) {
$('.offline-button').addClass('loading');
$('.offline-button').addClass('fa-pulse');
} else {
$('.offline-button').removeClass('loading');
$('.offline-button').removeClass('fa-pulse');
}
}
function socketUpdateOfflineVideoSource(resourceId) {
if (avideoSocketIsActive()) {
sendSocketMessageToResourceId({}, 'replaceVideoSourcesPerOfflineVersion', resourceId)
}
}
function getFirstOfflineAttachmentResolution(video) {
if (empty(video._attachments)) {
return false;
}
for (var i in video._attachments) {
if (i !== 'poster') {
return i;
}
}
return false;
}
function mapOfflineVideosId(doc) {
emit(doc.videos_id);
}
var offlineVideoDBPouch;
async function createOfflineDatabase(alsoDelete) {
if (!empty(alsoDelete)) {
return await offlineVideoDBPouch.destroy(function (err, response) {
if (err) {
return console.log(err);
} else {
offlineVideoDBPouch = new PouchDB(offlineVideoDbName);
}
});
} else {
offlineVideoDBPouch = new PouchDB(offlineVideoDbName);
}
return offlineVideoDBPouch;
}
$(document).ready(function () {
createOfflineDatabase(false);
replaceVideoSourcesPerOfflineVersion();
});

View file

@ -1,293 +0,0 @@
<?php
global $global, $config;
if (!isset($global['systemRootPath'])) {
require_once '../../videos/configuration.php';
}
$videos_id = intval(@$_REQUEST['videos_id']);
if (empty($videos_id)) {
forbiddenPage('Videos ID is required');
}
if (!User::canWatchVideo($videos_id)) {
forbiddenPage('you cannot watch this video');
}
$types = Video::getVideoTypeFromId($videos_id);
$video = Video::getVideoLight($videos_id);
$sources = getVideosURL_V2($video['filename']);
$sourcesResolutions = array();
$mainResolution = false;
foreach ($sources as $key => $value) {
if (preg_match('/^mp4_([0-9]+)/', $key, $matches)) {
$option = array('url' => $value['url'], 'path' => $value['path'], 'resolution' => $matches[1]);
$sourcesResolutions[] = $option;
if ($option['resolution'] == 480) {
$mainResolution = $option;
}
}else if (preg_match('/^m3u8_?([0-9]+)?/', $key, $matches)) {
$resolution = 'auto';
if(!empty($matches[1])){
$resolution = $matches[1];
}
$option = array('url' => $value['url'], 'path' => $value['path'], 'resolution' => $resolution);
$sourcesResolutions[] = $option;
if ($option['resolution'] == 480) {
$mainResolution = $option;
}
}
}
if (empty($mainResolution) && !empty($sourcesResolutions)) {
$mainResolution = $sourcesResolutions[0];
}
//var_dump($mainResolution);exit;
function createOfflineDownloadPanel($videos_id, $option, $class = 'col-xs-6') {
?>
<div class="<?php echo $class; ?>">
<div class="panel panel-default videos_offline_<?php echo $videos_id; ?>_<?php echo $option['resolution']; ?>">
<div class="panel-heading clearfix">
<button class="btn btn-danger" onclick='_deleteOfflineVideo(<?php echo json_encode($option['resolution']); ?>);'>
<i class="fas fa-trash"></i> <?php echo __('Delete'); ?> <span class="badge"><?php echo humanFileSize(filesize($option['path'])); ?></span>
</button>
<button class="btn btn-warning" onclick='_downloadOfflineVideo(<?php echo json_encode($option['url']); ?>, <?php echo json_encode($option['resolution']); ?>);'>
<i class="fas fa-download"></i> <?php echo __('Download'); ?> <span class="badge"><?php echo humanFileSize(filesize($option['path'])); ?></span>
</button>
<button class="btn btn-success hidden" onclick='_updateVideo(<?php echo json_encode($videos_id); ?>);'>
<i class="fas fa-sync"></i> <?php echo __('Renew'); ?>
</button>
<button class="btn btn-primary pull-right" onclick='deleteAllOfflineDatabase();'>
<i class="fas fa-times"></i> <?php echo __('Delete All'); ?>
</button>
</div>
<div class="panel-body">
<ul class="list-group">
<li class="list-group-item"><?php echo __('Resolution') ?> <span class="badge"><?php echo $option['resolution']; ?></span></li>
</ul>
</div>
<div class="panel-footer">
<div class="progress">
<div class="progress-bar progress-bar-striped active" role="progressbar"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0;">
0%
</div>
</div>
</div>
</div>
</div>
<?php
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="view/img/favicon.ico">
<title>Download Video</title>
<?php
//echo AVideoPlugin::getHeadCode();
include $global['systemRootPath'] . 'view/include/head.php';
?>
<link href="<?php echo getURL('plugin/PlayerSkins/offlineVideo.css'); ?>" rel="stylesheet" type="text/css"/>
</head>
<body class="<?php echo $global['bodyClass']; ?>">
<?php
include $global['systemRootPath'] . 'view/include/navbar.php';
?>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
</div>
<div class="panel-body offlinevideos tabbable-line">
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#offlineVideo"><?php echo __('Offline Video'); ?></a></li>
<li><a data-toggle="tab" href="#offlineVideoAdvanced"><?php echo __('Advanced'); ?></a></li>
<li><a data-toggle="tab" href="#offlineVideoAll"><?php echo __('All Videos'); ?></a></li>
</ul>
<div class="tab-content">
<div id="offlineVideo" class="tab-pane fade in active">
<div class="row">
<div class="col-xs-6">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<?php
echo Video::getVideosListItem($video['id']);
?>
</div>
<div class="panel-body">
<ul class="list-group">
<li class="list-group-item">
<?php echo __('Total Size') ?> <span class="badge"><?php echo humanFileSize($video['filesize']); ?></span>
</li>
</ul>
</div>
</div>
</div>
<div class="col-xs-6">
<?php
createOfflineDownloadPanel($videos_id, $mainResolution, '');
?>
</div>
</div>
</div>
<div id="offlineVideoAdvanced" class="tab-pane fade">
<div class="row">
<?php
foreach ($sourcesResolutions as $key => $option) {
createOfflineDownloadPanel($videos_id, $option);
}
?>
</div>
</div>
<div id="offlineVideoAll" class="tab-pane fade">
<div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12 bottom-border videoListItem hidden" id="offlineVideoTemplate">
<div class="col-lg-5 col-sm-5 col-xs-5 nopadding thumbsImage videoLink h6">
<div class="galleryVideo">
<a href="" class="videoLink">
<img
src=""
class="thumbsJPG img-responsive text-center" height="130"
style="">
</a>
<time class="duration"></time>
</div>
</div>
<div class="col-lg-7 col-sm-7 col-xs-7 videosDetails">
<a href="" class="videoLink">
<div class="text-uppercase row">
<strong class="title"></strong>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="panel-footer">
</div>
</div>
</div>
<?php
include $global['systemRootPath'] . 'view/include/footer.php';
?>
<script>
const offlineVideoDbName = 'videos_offlineDb_<?php echo User::getId(); ?>';
var mediaId = <?php echo $videos_id; ?>;
</script>
<script src="<?php echo getURL('node_modules/pouchdb/dist/pouchdb.min.js'); ?>" type="text/javascript"></script>
<script src="<?php echo getURL('plugin/PlayerSkins/offlineVideo.js'); ?>" type="text/javascript"></script>
<script>
$(document).ready(function () {
listAllOfflineVideo();
});
function deleteAllOfflineDatabase() {
createOfflineDatabase(true).then(function (resp) {
listAllOfflineVideo();
}).catch(function (e) {
console.log("deleteAllOfflineDatabase", e);
});
}
async function listAllOfflineVideoAvailable() {
var collection = await getAllOfflineVideoAvailable();
console.log('listAllOfflineVideoAvailable', collection);
$('#offlineVideoAll .offlineVideoAvailable').remove();
var model = $('#offlineVideoTemplate').clone();
model.attr('id', '');
model.removeClass('hidden');
model.addClass('offlineVideoAvailable');
for (var i in collection.rows) {
var video = collection.rows[i].doc;
if (typeof video !== 'object') {
continue;
}
//console.log("replaceVideoSourcesPerOfflineVersionFromVideosId video: ",video);
var fileBlob = await offlineVideoDBPouch.getAttachment(video._id, 'poster');
var source = createImageSourceFromBlob(fileBlob, 0);
var newVideo = $(model).clone();
newVideo.find('.videoLink').attr('href', video.link);
newVideo.find('.thumbsJPG').attr('src', source.src);
newVideo.find('.duration').html(video.duration);
newVideo.find('.title').html(video.title);
$('#offlineVideoAll > .row').append(newVideo);
console.log('listAllOfflineVideoAvailable video', video, newVideo);
}
}
async function listAllOfflineVideo() {
videos_id = <?php echo $videos_id; ?>;
var collection = await getAllOfflineVideoPouch(videos_id);
console.log('listAllOfflineVideo', collection);
$('.panel').removeClass('panel-success');
$('.panel').addClass('panel-default');
changeProgressBarOfflineVideo('.progress', 0);
for (var i in collection.rows) {
var video = collection.rows[i].doc;
if (typeof video !== 'object') {
continue;
}
console.log('listAllOfflineVideo video', video);
for (var i in video._attachments) {
if (i == 'poster') {
continue;
}
var elemSelector = '.videos_offline_' + video.videos_id + '_' + i;
$(elemSelector).removeClass('panel-default');
$(elemSelector).addClass('panel-success');
changeProgressBarOfflineVideo(elemSelector + ' .progress', 100);
}
}
}
async function _downloadOfflineVideo(src, resolution) {
var elemSelector = ".videos_offline_<?php echo $videos_id; ?>_" + resolution;
var progressBarSelector = elemSelector + " .progress";
$(elemSelector).addClass('isDownloading');
var response = await fetchVideoFromNetwork(src, 'video/mp4', resolution, progressBarSelector).then(function (video) {
console.log("_downloadOfflineVideo: ", video);
listAllOfflineVideo();
socketUpdateOfflineVideoSource(<?php echo json_encode($_REQUEST['socketResourceId']); ?>);
}).catch(function (e) {
console.log("_downloadOfflineVideo Error: ", e);
});
$(elemSelector).removeClass('isDownloading');
return response;
}
async function _deleteOfflineVideo(resolution) {
var elemSelector = ".videos_offline_<?php echo $videos_id; ?>_" + resolution;
$(elemSelector).addClass('isDeleting');
var response = await deleteOfflineVideoPouch(<?php echo $videos_id; ?>, resolution).then((video) => {
console.log('_deleteOfflineVideo', video);
listAllOfflineVideo();
socketUpdateOfflineVideoSource(<?php echo json_encode($_REQUEST['socketResourceId']); ?>);
});
$(elemSelector).removeClass('isDeleting');
return response;
}
</script>
<?php
if(!empty($types->m3u8) && AVideoPlugin::isEnabledByName('VideoHLS')){
include $global['systemRootPath'].'plugin/VideoHLS/downloadHLS.php';
}
?>
</body>
</html>

View file

@ -42,8 +42,4 @@
}
.vjs-thumbnail-holder {
margin-bottom: 10px;
}
.playingOfflineVideo #main-video #mainVideo{
}

View file

@ -292,52 +292,9 @@ unset($_POST['current']);
$class = '';
?>
<div class="col-lg-2 col-md-4 col-sm-4 col-xs-6 galleryVideo <?php echo $class; ?> " id="<?php echo $value['id']; ?>" style="padding: 1px;">
<a class="aspectRatio16_9" href="<?php echo $episodeLink; ?>" title="<?php echo $value['title']; ?>" style="margin: 15px 0; overflow: visible;" >
<img src="<?php echo $poster; ?>" alt="<?php echo $value['title']; ?>" class="img img-responsive <?php echo $img_portrait; ?> rotate<?php echo $value['rotation']; ?>" />
<?php
if ($value['type'] !== 'pdf' && $value['type'] !== 'article' && $value['type'] !== 'serie') {
?>
<span class="duration"><?php echo Video::getCleanDuration($value['duration']); ?></span>
<div class="progress" style="height: 3px; margin-bottom: 2px;">
<div class="progress-bar progress-bar-danger" role="progressbar" style="width: <?php echo $value['progress']['percent'] ?>%;" aria-valuenow="<?php echo $value['progress']['percent'] ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<?php
}
if (User::isLogged() && !empty($program)) {
?>
<div class="galleryVideoButtons">
<?php
//var_dump($value['isWatchLater'], $value['isFavorite']);
if ($value['isWatchLater']) {
$watchLaterBtnAddedStyle = '';
$watchLaterBtnStyle = "display: none;";
} else {
$watchLaterBtnAddedStyle = "display: none;";
$watchLaterBtnStyle = '';
}
if ($value['isFavorite']) {
$favoriteBtnAddedStyle = '';
$favoriteBtnStyle = "display: none;";
} else {
$favoriteBtnAddedStyle = "display: none;";
$favoriteBtnStyle = '';
}
?>
<button onclick="addVideoToPlayList(<?php echo $value['id']; ?>, false, <?php echo $value['watchLaterId']; ?>);
return false;" class="btn btn-dark btn-xs watchLaterBtnAdded watchLaterBtnAdded<?php echo $value['id']; ?>" title="<?php echo __("Added On Watch Later"); ?>" style="color: #4285f4;<?php echo $watchLaterBtnAddedStyle; ?>" ><i class="fas fa-check"></i></button>
<button onclick="addVideoToPlayList(<?php echo $value['id']; ?>, true, <?php echo $value['watchLaterId']; ?>);
return false;" class="btn btn-dark btn-xs watchLaterBtn watchLaterBtn<?php echo $value['id']; ?>" title="<?php echo __("Watch Later"); ?>" style="<?php echo $watchLaterBtnStyle; ?>" ><i class="fas fa-clock"></i></button>
<br>
<button onclick="addVideoToPlayList(<?php echo $value['id']; ?>, false, <?php echo $value['favoriteId']; ?>);
return false;" class="btn btn-dark btn-xs favoriteBtnAdded favoriteBtnAdded<?php echo $value['id']; ?>" title="<?php echo __("Added On Favorite"); ?>" style="color: #4285f4; <?php echo $favoriteBtnAddedStyle; ?>"><i class="fas fa-check"></i></button>
<button onclick="addVideoToPlayList(<?php echo $value['id']; ?>, true, <?php echo $value['favoriteId']; ?>);
return false;" class="btn btn-dark btn-xs favoriteBtn favoriteBtn<?php echo $value['id']; ?> faa-parent animated-hover" title="<?php echo __("Favorite"); ?>" style="<?php echo $favoriteBtnStyle; ?>" ><i class="fas fa-heart faa-pulse faa-fast" ></i></button>
</div>
<?php }
?>
</a>
<?php
echo Video::getVideoImagewithHoverAnimationFromVideosId($value['id']);
?>
<a class="h6 galleryLink hrefLink" href="<?php echo $episodeLink; ?>" title="<?php echo getSEOTitle($value['title']); ?>">
<strong class="title"><?php echo getSEOTitle($value['title']); ?></strong>
</a>

View file

@ -100,7 +100,8 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
$currentSerieVideos_id = 0;
} else {
$currentSerieVideos_id = $isASerie['id'];
} ?>
}
?>
<br>
<div class="panel panel-default program" playListId="<?php echo $program['id']; ?>">
<div class="panel-heading">
@ -109,13 +110,14 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
<?php
if (!empty($videosArrayId)) {
$link = PlayLists::getLink($program['id']); ?>
$link = PlayLists::getLink($program['id']);
?>
<a href="<?php echo $link; ?>" class="btn btn-xs btn-default playAll hrefLink" ><span class="fa fa-play"></span> <?php echo __("Play All"); ?></a><?php echo $playListButtons; ?>
<?php
echo PlayLists::getPlayLiveButton($program['id']);
}
if ($isMyChannel) {
?>
if ($isMyChannel) {
?>
<script>
$(function () {
$("#sortable<?php echo $program['id']; ?>").sortable({
@ -139,8 +141,7 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
</ul>
</div>
<div class="pull-right btn-group" style="display: inline-flex;">
<?php
echo PlayLists::getShowOnTVSwitch($program['id']); ?>
<?php echo PlayLists::getShowOnTVSwitch($program['id']); ?>
<?php
if ($program['status'] != "favorite" && $program['status'] != "watch_later") {
if (AVideoPlugin::isEnabledByName("PlayLists")) {
@ -180,8 +181,8 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
});
</script>
<?php
} ?>
<?php }
?>
<button class="btn btn-xs btn-danger deletePlaylist" playlist_id="<?php echo $program['id']; ?>" data-toggle="tooltip" title="<?php echo __('Delete'); ?>" ><i class="fas fa-trash"></i> <span class="hidden-xs hidden-sm"><?php echo __("Delete"); ?></span></button>
<button class="btn btn-xs btn-primary renamePlaylist" playlist_id="<?php echo $program['id']; ?>" data-toggle="tooltip" title="<?php echo __('Rename'); ?>" ><i class="fas fa-edit"></i> <span class="hidden-xs hidden-sm"><?php echo __("Rename"); ?></span></button>
<button class="btn btn-xs btn-success" onclick="openVideoSearch(<?php echo $currentSerieVideos_id; ?>)" playlist_id="<?php echo $program['id']; ?>" data-toggle="tooltip" title="<?php echo __('Add to Program'); ?>" ><i class="fas fa-plus"></i> <span class="hidden-xs hidden-sm"><?php echo __("Add"); ?></span></button>
@ -189,21 +190,24 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
<span class="fa fa-lock" id="statusPrivate<?php echo $program['id']; ?>" style="color: red; <?php
if ($program['status'] !== 'private') {
echo ' display: none;';
} ?> " data-toggle="tooltip" title="<?php echo __('This playlist is private, click to make it public'); ?>" ></span>
}
?> " data-toggle="tooltip" title="<?php echo __('This playlist is private, click to make it public'); ?>" ></span>
<span class="fa fa-globe" id="statusPublic<?php echo $program['id']; ?>" style="color: green; <?php
if ($program['status'] !== 'public') {
echo ' display: none;';
} ?>" data-toggle="tooltip" title="<?php echo __('This playlist is public, click to make it unlisted'); ?>" ></span>
}
?>" data-toggle="tooltip" title="<?php echo __('This playlist is public, click to make it unlisted'); ?>" ></span>
<span class="fa fa-eye-slash" id="statusUnlisted<?php echo $program['id']; ?>" style="color: gray; <?php
if ($program['status'] !== 'unlisted') {
echo ' display: none;';
} ?>" data-toggle="tooltip" title="<?php echo __('This playlist is unlisted, click to make it private'); ?>" ></span>
}
?>" data-toggle="tooltip" title="<?php echo __('This playlist is unlisted, click to make it private'); ?>" ></span>
</button>
<?php
} ?>
<?php }
?>
</div>
<?php
} ?>
<?php }
?>
</div>
<?php
@ -213,44 +217,37 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
<div class="panel-body">
<?php
$_REQUEST['user_id'] = $program['users_id'];
$_REQUEST['playlists_id'] = $program['id'];
include $global['systemRootPath'] . 'plugin/PlayLists/epg.html.php'; ?>
$_REQUEST['playlists_id'] = $program['id'];
include $global['systemRootPath'] . 'plugin/PlayLists/epg.html.php';
?>
<div id="sortable<?php echo $program['id']; ?>" style="list-style: none;">
<?php
$count = 0;
foreach ($videosP as $value) {
$episodeLink = "{$global['webSiteRootURL']}program/{$program['id']}/{$count}";
$count++;
if (empty($value['created'])) {
continue;
}
$img_portrait = ($value['rotation'] === "90" || $value['rotation'] === "270") ? "img-portrait" : "";
$name = User::getNameIdentificationById($value['users_id']);
foreach ($videosP as $value) {
$episodeLink = "{$global['webSiteRootURL']}program/{$program['id']}/{$count}";
$count++;
if (empty($value['created'])) {
continue;
}
$img_portrait = ($value['rotation'] === "90" || $value['rotation'] === "270") ? "img-portrait" : "";
$name = User::getNameIdentificationById($value['users_id']);
$images = Video::getImageFromFilename($value['filename'], $value['type'], true);
$imgGif = $images->thumbsGif;
$poster = $images->thumbsJpg;
$class = '';
$style = '';
if ($count > 6) {
$class = "showMoreLess{$program['id']}";
$style = "display: none;";
} ?>
$images = Video::getImageFromFilename($value['filename'], $value['type'], true);
$imgGif = $images->thumbsGif;
$poster = $images->thumbsJpg;
$class = '';
$style = '';
if ($count > 6) {
$class = "showMoreLess{$program['id']}";
$style = "display: none;";
}
?>
<li class="col-lg-2 col-md-4 col-sm-4 col-xs-6 galleryVideo showMoreLess <?php echo $class; ?> " id="<?php echo $value['id']; ?>" style="padding: 1px; <?php echo $style; ?>">
<div class="panel panel-default" playListId="<?php echo $program['id']; ?>" style="min-height: 215px;">
<div class="panel-body" style="overflow: hidden;">
<a class="aspectRatio16_9" href="<?php echo $episodeLink; ?>" title="<?php echo $value['title']; ?>" style="margin: 15px 0; overflow: visible;" >
<img src="<?php echo $poster; ?>" alt="<?php echo $value['title']; ?>" class="img img-responsive <?php echo $img_portrait; ?> rotate<?php echo $value['rotation']; ?>" />
<?php
if ($value['type'] !== 'pdf' && $value['type'] !== 'article' && $value['type'] !== 'serie') {
?>
<span class="duration"><?php echo Video::getCleanDuration($value['duration']); ?></span>
<div class="progress" style="height: 3px; margin-bottom: 2px;">
<div class="progress-bar progress-bar-danger" role="progressbar" style="width: <?php echo $value['progress']['percent'] ?>%;" aria-valuenow="<?php echo $value['progress']['percent'] ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<?php
} ?>
</a>
<?php
echo Video::getVideoImagewithHoverAnimationFromVideosId($value['id']);
?>
<a class="h6 galleryLink hrefLink" href="<?php echo $episodeLink; ?>" title="<?php echo getSEOTitle($value['title']); ?>">
<strong class="title"><?php echo getSEOTitle($value['title']); ?></strong>
</a>
@ -258,16 +255,17 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
<div class="galleryTags">
<?php
$value['tags'] = Video::getTags($value['id']);
foreach ($value['tags'] as $value2) {
if (is_array($value2)) {
$value2 = (object) $value2;
}
if ($value2->label === __("Group")) {
?>
foreach ($value['tags'] as $value2) {
if (is_array($value2)) {
$value2 = (object) $value2;
}
if ($value2->label === __("Group")) {
?>
<span class="label label-<?php echo $value2->type; ?>"><?php echo $value2->text; ?></span>
<?php
}
} ?>
}
}
?>
</div>
<?php
if (empty($advancedCustom->doNotDisplayViews)) {
@ -278,18 +276,16 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
<?php echo number_format($value['views_count'], 0); ?> <?php echo __("Views"); ?>
</span>
</div>
<?php
} ?>
<?php }
?>
<div>
<i class="far fa-clock"></i>
<?php
echo humanTiming(strtotime($value['videoCreation'])), " ", __('ago'); ?>
<?php echo humanTiming(strtotime($value['videoCreation'])), " ", __('ago'); ?>
</div>
<div>
<i class="fa fa-user"></i>
<?php
echo $name; ?>
<?php echo $name; ?>
</div>
<?php
if (Video::canEdit($value['id'])) {
@ -299,8 +295,8 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
</div>
<?php
} ?>
<?php }
?>
<?php
if ($isMyChannel) {
?>
@ -316,8 +312,8 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
<button class="btn btn-sm btn-xs sortNow"><i class="fas fa-check-square"></i></button>
</span>
</div>
<?php
} ?>
<?php }
?>
</div>
</div>
</div>
@ -326,13 +322,14 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
if ($count % 6 === 0) {
echo '<div class="clearfix hidden-md hidden-sm hidden-xs"></div>';
}
if ($count % 3 === 0) {
echo '<div class="clearfix hidden-lg hidden-xs"></div>';
}
if ($count % 2 === 0) {
echo '<div class="clearfix hidden-md hidden-sm hidden-lg"></div>';
}
} ?>
if ($count % 3 === 0) {
echo '<div class="clearfix hidden-lg hidden-xs"></div>';
}
if ($count % 2 === 0) {
echo '<div class="clearfix hidden-md hidden-sm hidden-lg"></div>';
}
}
?>
</div>
</div>
@ -345,15 +342,15 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
<button class="btn btn-default btn-xs btn-sm showMoreLessBtn showMoreLessBtn<?php echo $program['id']; ?>" onclick="$('.showMoreLessBtn<?php echo $program['id']; ?>').toggle();
$('.<?php echo $class; ?>').slideUp();" style="display: none;"><i class="fas fa-angle-up"></i> <?php echo __('Show Less'); ?></button>
<?php
}
if ($isMyChannel && !empty($videosArrayId)) {
?>
}
if ($isMyChannel && !empty($videosArrayId)) {
?>
<span class="label label-info" ><i class="fa fa-info-circle"></i> <?php echo __("Drag and drop to sort"); ?></span>
<?php
} ?>
<?php }
?>
</div>
<?php
} ?>
<?php }
?>
</div>
<?php
@ -472,11 +469,11 @@ $playListsObj = AVideoPlugin::getObjectData("PlayLists");
$(function () {
<?php
if (count($programs) <= 1 || !empty($palyListsObj->expandPlayListOnChannels)) {
?>
?>
$('.showMoreLess').slideDown();
$('.showMoreLessBtn').toggle();
<?php
}
}
?>
$('.removeVideo').click(function () {
currentObject = this;

View file

@ -17,6 +17,7 @@ body.fullscreen {
padding: 0 !important;
margin: 0 !important;
}
/*
.videoLink > .duration,
time.duration{
position: absolute;
@ -28,6 +29,24 @@ time.duration{
font-size: 0.9em;
border-radius: 5px;
}
*/
time.duration {
position: absolute;
background: rgba(0, 0, 0, 0.4)!important;
padding: 1px 4px;
color: #FFF;
top: 5px;
left: 5px;
font-size: 12px;
border-radius: 5px;
opacity: 0.7;
}
.thumbsImageContainer{
position: relative;
}
.thumbsImageContainer .thumbsImage{
border: none;
}
.videoLink .glyphicon-play-circle {
transition: all 0.3s ease-in-out;
top: 50%;
@ -423,16 +442,6 @@ footer ul.list-inline li {
.videosDetails {
padding-left: 20px;
}
.divMainVideo .duration {
position: absolute;
background: rgba(0, 0, 0, 0.6)!important;
padding: 3px;
color: #FFF;
bottom: 5px;
right: 25px;
font-size: 0.9em;
border-radius: 5px;
}
.autoplay span span {
margin: 0 5px;
font-weight: bold;

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -53,6 +53,7 @@ showAlertMessage();
<script src="<?php echo getURL('node_modules/moment-timezone/builds/moment-timezone-with-data.min.js'); ?>"></script>
<script src="<?php echo getURL('view/js/script.js'); ?>" type="text/javascript"></script>
<script src="<?php echo getURL('node_modules/jquery-ui-dist/jquery-ui.min.js'); ?>" type="text/javascript"></script>
<script src="<?php echo getURL('node_modules/pouchdb/dist/pouchdb.min.js'); ?>" type="text/javascript"></script>
<!--
<script src="<?php echo getURL('node_modules/wow.js/dist/wow.min.js'); ?>" type="text/javascript"></script>
<script>

View file

@ -1318,6 +1318,29 @@ function avideoAlertOnce(title, msg, type, uid) {
}
}
async function avideoConfirm(msg) {
var span = document.createElement("span");
span.innerHTML = msg;
var response = await swal({
title: 'Confrim',
content: span,
icon: 'warning',
closeOnClickOutside: false,
closeModal: true,
buttons: {
cancel: "Cancel",
confirm: {
text: "Confirm",
value: "confirm",
className: "btn-danger",
},
}
}).then(function (value) {
return value=='confirm';
});
return response;
}
function avideoAlertOnceForceConfirm(title, msg, type) {
var span = document.createElement("span");
span.innerHTML = msg;
@ -2686,26 +2709,26 @@ $(document).ready(function () {
setToolTips();
}, 1000);
/*
$(".thumbsImage").on("mouseenter", function () {
gifId = $(this).find(".thumbsGIF").attr('id');
$(".thumbsGIF").fadeOut();
if (gifId != undefined) {
id = gifId.replace('thumbsGIF', '');
var gif = $(this).find(".thumbsGIF");
var jpg = $(this).find(".thumbsGIF");
gif.height(jpg.height());
gif.width(jpg.width());
try {
gif.lazy({effect: 'fadeIn'});
} catch (e) {
}
gif.stop(true, true).fadeIn();
}
});
$(".thumbsImage").on("mouseleave", function () {
$(this).find(".thumbsGIF").stop(true, true).fadeOut();
});
*/
$(".thumbsImage").on("mouseenter", function () {
gifId = $(this).find(".thumbsGIF").attr('id');
$(".thumbsGIF").fadeOut();
if (gifId != undefined) {
id = gifId.replace('thumbsGIF', '');
var gif = $(this).find(".thumbsGIF");
var jpg = $(this).find(".thumbsGIF");
gif.height(jpg.height());
gif.width(jpg.width());
try {
gif.lazy({effect: 'fadeIn'});
} catch (e) {
}
gif.stop(true, true).fadeIn();
}
});
$(".thumbsImage").on("mouseleave", function () {
$(this).find(".thumbsGIF").stop(true, true).fadeOut();
});
*/
lazyImage();
$("a").each(function () {
var location = window.location.toString()
@ -2921,5 +2944,5 @@ function isPromise(p) {
}
function replaceAll(str, find, replace) {
return str.replace(new RegExp(find, 'g'), replace);
return str.replace(new RegExp(find, 'g'), replace);
}

View file

@ -49,20 +49,14 @@ $description = getSEODescription(emptyHTML($video['description']) ? $video['titl
<div class="row bgWhite list-group-item">
<div class="row divMainVideo">
<div class="col-xs-4 col-sm-4 col-md-4">
<img src="<?php echo $img; ?>" alt="<?php echo getSEOTitle($video['title']); ?>" class="img img-responsive <?php echo $img_portrait; ?> rotate<?php echo $video['rotation']; ?>" height="130" itemprop="thumbnail" />
<?php
if (isToShowDuration($video['type'])) {
?>
<time class="duration" itemprop="duration" datetime="<?php echo Video::getItemPropDuration($video['duration']); ?>" ><?php echo Video::getCleanDuration($video['duration']); ?></time>
<?php
}
echo Video::getVideoImagewithHoverAnimationFromVideosId($video['id'], true, false);
?>
<span itemprop="thumbnailUrl" content="<?php echo $img; ?>" />
<span itemprop="contentURL" content="<?php echo Video::getLink($video['id'], $video['clean_title']); ?>" />
<span itemprop="embedURL" content="<?php echo Video::getLink($video['id'], $video['clean_title'], true); ?>" />
<span itemprop="uploadDate" content="<?php echo $video['created']; ?>" />
<span itemprop="description" content="<?php echo $description; ?>" />
<span itemprop="thumbnailUrl" content="<?php echo $img; ?>" ></span>
<span itemprop="contentURL" content="<?php echo Video::getLink($video['id'], $video['clean_title']); ?>"></span>
<span itemprop="embedURL" content="<?php echo Video::getLink($video['id'], $video['clean_title'], true); ?>" ></span>
<span itemprop="uploadDate" content="<?php echo $video['created']; ?>"></span>
<span itemprop="description" content="<?php echo $description; ?>"></span>
</div>
<div class="col-xs-8 col-sm-8 col-md-8">
<h2 itemprop="name">

View file

@ -1,33 +1,27 @@
<div class="col-lg-12 col-sm-12 col-xs-12 bottom-border videoListItem" id="{divID}" style='{style}' >
<div class="col-lg-5 col-sm-5 col-xs-5 nopadding thumbsImage videoLink h6" >
<div class="galleryVideo">
<a href="{link}" title="{title}">
<img src="{imgJPGLow}" data-src="{imgJPGHight}" alt="{title}" class="thumbsJPG img-responsive text-center rotate" height="130" />
{imgGifHTML}
</a>
{timeHTML}
{loggedUserHTML}
</div>
<div class="progress" style="height: 3px; margin-bottom: 2px;">
<div class="progress-bar progress-bar-danger" role="progressbar"
style="width: {progress}%;" aria-valuenow="{progress}" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
<div class="col-lg-7 col-sm-7 col-xs-7 videosDetails">
<a href="{link}" title="{title}" >
<div class="text-uppercase row"><strong class="title">{title}</strong></div>
</a>
<div class="details row">
<div class="pull-left">
<a class="label label-default" href="{categoryLink}" data-toggle="tooltip" title="{category}" >
<span class="{categoryIcon}"></span>
</a>
{tagsHTML}
</div>
{viewsHTML}
</div>
<div class="row" style="margin-top: 5px;">
{creator}
</div>
</div>
<div class="col-lg-12 col-sm-12 col-xs-12 bottom-border videoListItem" id="{divID}" style='{style}' >
<div class="col-lg-5 col-sm-5 col-xs-5 nopadding videoLink h6" >
<div class="galleryVideo">
<a href="{link}" title="{title}">
{thumbsImage}
</a>
{loggedUserHTML}
</div>
</div>
<div class="col-lg-7 col-sm-7 col-xs-7 videosDetails">
<a href="{link}" title="{title}" >
<div class="text-uppercase row"><strong class="title">{title}</strong></div>
</a>
<div class="details row">
<div class="pull-left">
<a class="label label-default" href="{categoryLink}" data-toggle="tooltip" title="{category}" >
<span class="{categoryIcon}"></span>
</a>
{tagsHTML}
</div>
{viewsHTML}
</div>
<div class="row" style="margin-top: 5px;">
{creator}
</div>
</div>
</div>