Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Polish stuff a bit
Signed-off-by: Carl Schwan <[email protected]>
  • Loading branch information
CarlSchwan committed Sep 27, 2022
commit 305c63ba3a6d3b15b4487dd9c22babbc4a592dc8
10 changes: 4 additions & 6 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @copyright Copyright (c) 2021 Frederic Ruget (douzebis) <[email protected]>
*
* @author Frederic Ruget (douzebis) <[email protected]>
* @author Carl Schwan <[email protected]>
*
* @license GNU AGPL version 3 or any later version
*
Expand All @@ -22,11 +23,8 @@
*/

return [
'ocs' => [
[
'name' => 'video#getTracks',
'url' => '/video/tracks',
'verb' => 'GET',
]
'routes' => [
/** @see \OCA\Viewer\Controller\VideoController */
[ 'name' => 'video#getTracks', 'url' => '/video/tracks', 'verb' => 'GET', ]
]
];
176,518 changes: 176,515 additions & 3 deletions js/viewer-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/viewer-main.js.map

Large diffs are not rendered by default.

45 changes: 22 additions & 23 deletions lib/Controller/VideoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,21 @@
use OCP\IRequest;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\AppFramework\APIController;
use OCP\L10N\IFactory;

use OCP\Files\File;
use OCP\Files\Node;
use OCP\Files\IRootFolder;
use OCP\IUserSession;

use OCA\Viewer\AppInfo\Application;

class VideoController extends OCSController {
class VideoController extends APIController {

/** @var IRootFolder */
private $rootFolder;

/** @var IFactory */
private $l10nFactory;

/** @var IUserSession */
private $userSession;
private IRootFolder $rootFolder;
private IFactory $l10nFactory;
private IUserSession $userSession;

public function __construct(
IRequest $request,
Expand All @@ -63,7 +59,7 @@ public function __construct(
/**
* @NoAdminRequired
*/
public function getTracks($videoPath): DataResponse {
public function getTracks(string $videoPath): DataResponse {
/**
* $videoPath is the path to the main video file, eg: 'mypath/movie.mkv'
* Return an array of found tracks associated with the main video.
Expand All @@ -73,10 +69,10 @@ public function getTracks($videoPath): DataResponse {
* - locale // (usually 2-letter) code for the language
*/
$locales = array_filter($this->l10nFactory->findAvailableLocales(),
function($v) {
function(array $v): bool {
// Discard codes that are more than 3 characters long
// Otherwise we get a list of 1500 candidate tracks !!
return (strlen($v['code']) <= 3);
return strlen($v['code']) <= 3;
});
$video = $this->rootFolder
->getUserFolder($this->userSession->getUser()->getUID())
Expand All @@ -85,24 +81,27 @@ function($v) {
$videoName = pathinfo($video->getFileInfo()->getPath())['filename'];
$candidateTracks = array_merge(
// List candidateTracks of the form 'video.<locale>.vtt'
array_map(function ($locale) use ($videoName) {
array_map(function (array $locale) use ($videoName): array {
return [
basename => $videoName . '.' . $locale['code'] . '.vtt',
language => $locale['name'],
locale => $locale['code']
'basename' => $videoName . '.' . $locale['code'] . '.vtt',
'language' => $locale['name'],
'locale' => $locale['code']
];
}, $locales),
// Add candidateTracks of the form '.video.<locale>.vtt' (dotted)
array_map(function ($locale) use ($videoName) {
array_map(function (array $locale) use ($videoName): array {
return [
basename => '.' . $videoName . '.' . $locale['code'] . '.vtt',
language => $locale['name'],
locale => $locale['code']
'basename' => '.' . $videoName . '.' . $locale['code'] . '.vtt',
'language' => $locale['name'],
'locale' => $locale['code']
];
}, $locales));

$dirContentNames = array_map(fn (Node $node) => $node->getName(), $videoDir->getDirectoryListing());

// Keep only tracks actually available in the video folder
$availableTracks = array_filter($candidateTracks, function($v) use ($videoDir) {
return $videoDir->nodeExists($v['basename']);
$availableTracks = array_filter($candidateTracks, function(array $v) use ($dirContentNames): bool {
return in_array($v['basename'], $dirContentNames);
});
return new DataResponse($availableTracks);
}
Expand Down
16 changes: 8 additions & 8 deletions src/components/Videos.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
@loadedmetadata="onLoadedMetadata">

<track v-for="track in tracks"
:key="track"
:key="track.davPath"
:src="track.davPath"
:label="track.language"
kind="captions"
Expand All @@ -67,7 +67,7 @@ import logger from '../services/logger.js'
import { extractFilePaths } from '../utils/fileUtils'
import getFileList from '../services/FileList'
import { dirname } from '@nextcloud/paths'
import { generateOcsUrl } from '@nextcloud/router'
import { generateUrl } from '@nextcloud/router'
import axios from '@nextcloud/axios'

const liveExt = ['jpg', 'jpeg', 'png']
Expand All @@ -79,9 +79,9 @@ export default {
name: 'Videos',

data() {
// This is required so that tracks is declared and reactive
// Otherwise updates may fail to make it to plyr
return { tracks: [] }
return {
tracks: [],
}
},

computed: {
Expand Down Expand Up @@ -153,12 +153,12 @@ export default {
// Fetch caption tracks and build HTML5 block
async fetchTracks() {
try {
const response = await axios.get(
generateOcsUrl('/apps/viewer/video/tracks'),
const { data } = await axios.get(
generateUrl('/apps/viewer/video/tracks'),
{ params: { videoPath: this.filename } }
)
const davDir = dirname(this.davPath)
this.tracks = Object.values(response.data.ocs.data).map(track => ({
this.tracks = Object.values(data).map(track => ({
davPath: davDir + '/' + track.basename,
language: track.language,
locale: track.locale,
Expand Down