video: allow transcoding everywhere

cap
Varun Patil 2022-12-02 22:23:43 -08:00
parent 874258dae9
commit e60d97ae5e
8 changed files with 74 additions and 42 deletions

View File

@ -121,6 +121,9 @@ class PublicController extends AuthPublicShareController
$policy->addAllowedScriptDomain('blob:'); $policy->addAllowedScriptDomain('blob:');
$policy->addAllowedMediaDomain('blob:'); $policy->addAllowedMediaDomain('blob:');
// Image editor
$policy->addAllowedConnectDomain('data:');
// Allow nominatim for metadata // Allow nominatim for metadata
$policy->addAllowedConnectDomain('nominatim.openstreetmap.org'); $policy->addAllowedConnectDomain('nominatim.openstreetmap.org');
$policy->addAllowedFrameDomain('www.openstreetmap.org'); $policy->addAllowedFrameDomain('www.openstreetmap.org');

View File

@ -34,17 +34,14 @@ class VideoController extends ApiBase
/** /**
* @NoAdminRequired * @NoAdminRequired
* *
* @PublicPage
*
* @NoCSRFRequired * @NoCSRFRequired
* *
* Transcode a video to HLS by proxy * Transcode a video to HLS by proxy
*/ */
public function transcode(string $client, string $fileid, string $profile): Http\Response public function transcode(string $client, int $fileid, string $profile): Http\Response
{ {
$user = $this->userSession->getUser();
if (null === $user) {
return new JSONResponse([], Http::STATUS_PRECONDITION_FAILED);
}
// Make sure not running in read-only mode // Make sure not running in read-only mode
if (false !== $this->config->getSystemValue('memories.no_transcode', 'UNSET')) { if (false !== $this->config->getSystemValue('memories.no_transcode', 'UNSET')) {
return new JSONResponse(['message' => 'Transcoding disabled'], Http::STATUS_FORBIDDEN); return new JSONResponse(['message' => 'Transcoding disabled'], Http::STATUS_FORBIDDEN);
@ -56,11 +53,10 @@ class VideoController extends ApiBase
} }
// Get file // Get file
$files = $this->rootFolder->getUserFolder($user->getUID())->getById($fileid); $file = $this->getUserFile($fileid);
if (0 === \count($files)) { if (!$file) {
return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND); return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND);
} }
$file = $files[0];
if (!($file->getPermissions() & \OCP\Constants::PERMISSION_READ)) { if (!($file->getPermissions() & \OCP\Constants::PERMISSION_READ)) {
return new JSONResponse(['message' => 'File not readable'], Http::STATUS_FORBIDDEN); return new JSONResponse(['message' => 'File not readable'], Http::STATUS_FORBIDDEN);
@ -250,7 +246,15 @@ class VideoController extends ApiBase
private function getUpstreamInternal($client, $path, $profile) private function getUpstreamInternal($client, $path, $profile)
{ {
$path = rawurlencode($path); $path = rawurlencode($path);
$ch = curl_init("http://127.0.0.1:47788/{$client}{$path}/{$profile}");
// Make sure query params are repeated
// For example, in folder sharing, we need the params on every request
$url = "http://127.0.0.1:47788/{$client}{$path}/{$profile}";
if ($params = $_SERVER['QUERY_STRING']) {
$url .= "?{$params}";
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HEADER, 0);

View File

@ -20,7 +20,7 @@ mv "exiftool-$exifver" exiftool
rm -rf *.zip exiftool/t exiftool/html rm -rf *.zip exiftool/t exiftool/html
chmod 755 exiftool/exiftool chmod 755 exiftool/exiftool
govod="0.0.22" govod="0.0.23"
echo "Getting go-vod $govod" echo "Getting go-vod $govod"
wget -q "https://github.com/pulsejet/go-vod/releases/download/$govod/go-vod-amd64" wget -q "https://github.com/pulsejet/go-vod/releases/download/$govod/go-vod-amd64"
wget -q "https://github.com/pulsejet/go-vod/releases/download/$govod/go-vod-aarch64" wget -q "https://github.com/pulsejet/go-vod/releases/download/$govod/go-vod-aarch64"

View File

@ -88,9 +88,11 @@ export default class Metadata extends Mixins(GlobalMixin) {
this.nominatim = null; this.nominatim = null;
let state = this.state; let state = this.state;
const res = await axios.get<any>( let url = generateUrl("/apps/memories/api/image/info/{id}", {
generateUrl("/apps/memories/api/image/info/{id}", { id: fileInfo.id }) id: fileInfo.id,
); });
url = utils.addQueryTokensToUrl(url);
const res = await axios.get<any>(url);
if (state !== this.state) return; if (state !== this.state) return;
this.baseInfo = res.data; this.baseInfo = res.data;

View File

@ -5,6 +5,7 @@ import axios from "@nextcloud/axios";
import { showError } from "@nextcloud/dialogs"; import { showError } from "@nextcloud/dialogs";
import { translate as t } from "@nextcloud/l10n"; import { translate as t } from "@nextcloud/l10n";
import { getCurrentUser } from "@nextcloud/auth"; import { getCurrentUser } from "@nextcloud/auth";
import { addQueryTokensToUrl } from "../services/Utils";
const config_noTranscode = loadState( const config_noTranscode = loadState(
"memories", "memories",
@ -115,12 +116,16 @@ class VideoContentSetup {
} }
getHLSsrc(content: any) { getHLSsrc(content: any) {
// Get base URL
const fileid = content.data.photo.fileid; const fileid = content.data.photo.fileid;
const baseUrl = generateUrl( let url = generateUrl(
`/apps/memories/api/video/transcode/${videoClientId}/${fileid}` `/apps/memories/api/video/transcode/${videoClientId}/${fileid}/index.m3u8`
); );
url = addQueryTokensToUrl(url);
return { return {
src: `${baseUrl}/index.m3u8`, src: url,
type: "application/x-mpegURL", type: "application/x-mpegURL",
}; };
} }
@ -227,13 +232,12 @@ class VideoContentSetup {
}); });
// Get correct orientation // Get correct orientation
axios let url = generateUrl("/apps/memories/api/image/info/{id}", {
.get<any>(
generateUrl("/apps/memories/api/image/info/{id}", {
id: content.data.photo.fileid, id: content.data.photo.fileid,
}) });
) url = addQueryTokensToUrl(url);
.then((response) => {
axios.get<any>(url).then((response) => {
content.data.exif = response.data?.exif; content.data.exif = response.data?.exif;
// Update only after video is ready // Update only after video is ready

View File

@ -602,11 +602,6 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
); );
} }
// Favorites
if (this.$route.name === "folder-share") {
query.set("folder_share", this.$route.params.token);
}
// Month view // Month view
if (this.isMonthView) { if (this.isMonthView) {
query.set("monthView", "1"); query.set("monthView", "1");
@ -614,6 +609,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
} }
// Create query string and append to URL // Create query string and append to URL
utils.addQueryTokens(query);
const queryStr = query.toString(); const queryStr = query.toString();
if (queryStr) { if (queryStr) {
url += "?" + queryStr; url += "?" + queryStr;

View File

@ -23,6 +23,7 @@ import { generateUrl } from "@nextcloud/router";
import camelcase from "camelcase"; import camelcase from "camelcase";
import { IFileInfo, IPhoto } from "../types"; import { IFileInfo, IPhoto } from "../types";
import { isNumber } from "./NumberUtils"; import { isNumber } from "./NumberUtils";
import { addQueryTokens } from "./Utils";
/** /**
* Get an url encoded path * Get an url encoded path
@ -153,9 +154,7 @@ const getPreviewUrl = function (
query.set("a", square ? "0" : "1"); query.set("a", square ? "0" : "1");
// Public preview // Public preview
if (vuerouter.currentRoute.name === "folder-share") { addQueryTokens(query);
query.set("folder_share", vuerouter.currentRoute.params.token);
}
return url + "?" + query.toString(); return url + "?" + query.toString();
}; };

View File

@ -237,6 +237,34 @@ export function getFolderRoutePath(basePath: string) {
return path; return path;
} }
/**
* Add any access tokens to query param if required
* @param query Query string
*/
export function addQueryTokens(query: URLSearchParams) {
if (vuerouter.currentRoute.name === "folder-share") {
query.set("folder_share", vuerouter.currentRoute.params.token);
}
}
/**
* Add query tokens to a string URL
* @param url URL to add tokens to
*/
export function addQueryTokensToUrl(url: string) {
const query = new URLSearchParams();
addQueryTokens(query);
if (query.toString()) {
if (url.indexOf("?") === -1) {
url += "?";
} else {
url += "&";
}
url += query.toString();
}
return url;
}
/** /**
* Get URL to live photo video part * Get URL to live photo video part
*/ */
@ -254,11 +282,7 @@ export function getLivePhotoVideoUrl(p: IPhoto, transcode: boolean) {
query.set("transcode", videoClientIdPersistent); query.set("transcode", videoClientIdPersistent);
} }
// Add auth token for public share addQueryTokens(query);
if (vuerouter.currentRoute.name === "folder-share") {
query.set("folder_share", vuerouter.currentRoute.params.token);
}
return url + "?" + query.toString(); return url + "?" + query.toString();
} }