livephoto: transcode Apple for HEVC (fix #234)

cap
Varun Patil 2022-11-29 13:30:08 -08:00
parent 8adedd1885
commit f5cfa095ce
7 changed files with 32 additions and 13 deletions

View File

@ -124,7 +124,7 @@ class VideoController extends ApiBase
} }
// Check data was received // Check data was received
if ($returnCode !== 200) { if (200 !== $returnCode) {
return new JSONResponse(['message' => 'Transcode failed'], Http::STATUS_INTERNAL_SERVER_ERROR); return new JSONResponse(['message' => 'Transcode failed'], Http::STATUS_INTERNAL_SERVER_ERROR);
} }
@ -210,6 +210,15 @@ class VideoController extends ApiBase
$name = $liveFile->getName(); $name = $liveFile->getName();
$blob = $liveFile->getContent(); $blob = $liveFile->getContent();
$mime = $liveFile->getMimeType(); $mime = $liveFile->getMimeType();
if ($this->request->getParam('transcode') && !$this->config->getSystemValue('memories.no_transcode', true)) {
// Only Apple uses HEVC for now, so pass this to the transcoder
// If this is H.264 it won't get transcoded anyway
$liveVideoPath = $liveFile->getStorage()->getLocalFile($liveFile->getInternalPath());
if ($this->getUpstream('livephoto', $liveVideoPath, 'max.mp4')) {
exit;
}
}
} }
} }
@ -242,20 +251,28 @@ class VideoController extends ApiBase
// Stream the response to the browser without reading it into memory // Stream the response to the browser without reading it into memory
$headersWritten = false; $headersWritten = false;
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $data) use (&$headersWritten) { curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($curl, $data) use (&$headersWritten, $profile) {
$returnCode = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE); $returnCode = (int) curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($returnCode === 200) { if (200 === $returnCode) {
// Write headers if just got the first chunk of data // Write headers if just got the first chunk of data
if (!$headersWritten) { if (!$headersWritten) {
$headersWritten = true; $headersWritten = true;
$contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE); $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
header("Content-Type: {$contentType}"); header("Content-Type: {$contentType}");
if (str_ends_with($profile, 'mp4')) {
// cache full video 24 hours
header('Cache-Control: max-age=86400, public');
} else {
// no caching of segments
header('Cache-Control: no-cache, no-store, must-revalidate'); header('Cache-Control: no-cache, no-store, must-revalidate');
}
http_response_code($returnCode); http_response_code($returnCode);
} }
print($data); echo $data;
ob_flush(); ob_flush();
flush(); flush();
@ -264,7 +281,7 @@ class VideoController extends ApiBase
} }
} }
return strlen($data); return \strlen($data);
}); });
// Start the request // Start the request

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.18" govod="0.0.19"
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

@ -31,7 +31,7 @@ class LivePhotoContentSetup {
video.autoplay = false; video.autoplay = false;
video.playsInline = true; video.playsInline = true;
video.preload = "none"; video.preload = "none";
video.src = utils.getLivePhotoVideoUrl(photo); video.src = utils.getLivePhotoVideoUrl(photo, true);
const div = document.createElement("div"); const div = document.createElement("div");
div.className = "memories-livephoto"; div.className = "memories-livephoto";

View File

@ -874,7 +874,7 @@ export default class Viewer extends Mixins(GlobalMixin) {
private async downloadCurrentLiveVideo() { private async downloadCurrentLiveVideo() {
const photo = this.currentPhoto; const photo = this.currentPhoto;
if (!photo) return; if (!photo) return;
window.location.href = utils.getLivePhotoVideoUrl(photo); window.location.href = utils.getLivePhotoVideoUrl(photo, false);
} }
/** Open the sidebar */ /** Open the sidebar */

View File

@ -133,7 +133,7 @@ export default class Photo extends Mixins(GlobalMixin) {
get videoUrl() { get videoUrl() {
if (this.data.liveid) { if (this.data.liveid) {
return utils.getLivePhotoVideoUrl(this.data); return utils.getLivePhotoVideoUrl(this.data, true);
} }
} }

View File

@ -240,10 +240,12 @@ export function getFolderRoutePath(basePath: string) {
/** /**
* Get URL to live photo video part * Get URL to live photo video part
*/ */
export function getLivePhotoVideoUrl(p: IPhoto) { export function getLivePhotoVideoUrl(p: IPhoto, transcode: boolean) {
return generateUrl( let url = generateUrl(
`/apps/memories/api/video/livephoto/${p.fileid}?etag=${p.etag}&liveid=${p.liveid}` `/apps/memories/api/video/livephoto/${p.fileid}?etag=${p.etag}&liveid=${p.liveid}`
); );
if (transcode) url += "&transcode=1";
return url;
} }
/** /**

View File

@ -204,7 +204,7 @@ export async function* deletePhotos(photos: IPhoto[]) {
photos photos
.filter((p) => p.liveid && !p.liveid.startsWith("self__")) .filter((p) => p.liveid && !p.liveid.startsWith("self__"))
.map(async (p) => { .map(async (p) => {
const url = utils.getLivePhotoVideoUrl(p) + "&format=json"; const url = utils.getLivePhotoVideoUrl(p, false) + "&format=json";
try { try {
const response = await axios.get(url); const response = await axios.get(url);
const data = response.data; const data = response.data;