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
if ($returnCode !== 200) {
if (200 !== $returnCode) {
return new JSONResponse(['message' => 'Transcode failed'], Http::STATUS_INTERNAL_SERVER_ERROR);
}
@ -210,6 +210,15 @@ class VideoController extends ApiBase
$name = $liveFile->getName();
$blob = $liveFile->getContent();
$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
$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);
if ($returnCode === 200) {
if (200 === $returnCode) {
// Write headers if just got the first chunk of data
if (!$headersWritten) {
$headersWritten = true;
$contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
header("Content-Type: {$contentType}");
header('Cache-Control: no-cache, no-store, must-revalidate');
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');
}
http_response_code($returnCode);
}
print($data);
echo $data;
ob_flush();
flush();
@ -264,7 +281,7 @@ class VideoController extends ApiBase
}
}
return strlen($data);
return \strlen($data);
});
// Start the request

View File

@ -20,7 +20,7 @@ mv "exiftool-$exifver" exiftool
rm -rf *.zip exiftool/t exiftool/html
chmod 755 exiftool/exiftool
govod="0.0.18"
govod="0.0.19"
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-aarch64"

View File

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

View File

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

View File

@ -133,7 +133,7 @@ export default class Photo extends Mixins(GlobalMixin) {
get videoUrl() {
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
*/
export function getLivePhotoVideoUrl(p: IPhoto) {
return generateUrl(
export function getLivePhotoVideoUrl(p: IPhoto, transcode: boolean) {
let url = generateUrl(
`/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
.filter((p) => p.liveid && !p.liveid.startsWith("self__"))
.map(async (p) => {
const url = utils.getLivePhotoVideoUrl(p) + "&format=json";
const url = utils.getLivePhotoVideoUrl(p, false) + "&format=json";
try {
const response = await axios.get(url);
const data = response.data;