livephoto: transcode Apple for HEVC (fix #234)
parent
8adedd1885
commit
f5cfa095ce
|
@ -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}");
|
||||
|
||||
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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue