1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-05 02:39:33 +02:00

Improve Video AP compatibility

Compat with text/html descriptions
Compat with SPDX for licences
Compat with missing sensitive attribute
Compat with missing tag attribute
Compat with missing video file magnet URI
Compat with missing streaming playlist segmentsSha256Url
Compat with optional comments/likes/dislikes/shares URI in video object

Add more debug logs when the object is not valid
This commit is contained in:
Chocobozzz 2024-05-31 11:31:52 +02:00
parent 1e3a5b25c3
commit 7c9f07e140
No known key found for this signature in database
GPG key ID: 583A612D890159BE
13 changed files with 215 additions and 124 deletions

View file

@ -16,7 +16,6 @@ import { isAPVideoFileUrlMetadataObject } from '@server/helpers/custom-validator
import { isArray } from '@server/helpers/custom-validators/misc.js'
import { isVideoFileInfoHashValid } from '@server/helpers/custom-validators/videos.js'
import { generateImageFilename } from '@server/helpers/image-utils.js'
import { logger } from '@server/helpers/logger.js'
import { getExtFromMimetype } from '@server/helpers/video.js'
import { MIMETYPES, P2P_MEDIA_LOADER_PEER_VERSION, PREVIEWS_SIZE, THUMBNAILS_SIZE } from '@server/initializers/constants.js'
import { generateTorrentFileName } from '@server/lib/paths.js'
@ -58,21 +57,6 @@ export function getFileAttributesFromUrl (
const attributes: FilteredModelAttributes<VideoFileModel>[] = []
for (const fileUrl of fileUrls) {
// Fetch associated magnet uri
const magnet = urls.filter(isAPMagnetUrlObject)
.find(u => u.height === fileUrl.height)
if (!magnet) throw new Error('Cannot find associated magnet uri for file ' + fileUrl.href)
const parsed = magnetUriDecode(magnet.href)
if (!parsed || isVideoFileInfoHashValid(parsed.infoHash) === false) {
throw new Error('Cannot parse magnet URI ' + magnet.href)
}
const torrentUrl = Array.isArray(parsed.xs)
? parsed.xs[0]
: parsed.xs
// Fetch associated metadata url, if any
const metadata = urls.filter(isAPVideoFileUrlMetadataObject)
.find(u => {
@ -84,14 +68,20 @@ export function getFileAttributesFromUrl (
const extname = getExtFromMimetype(MIMETYPES.VIDEO.MIMETYPE_EXT, fileUrl.mediaType)
const resolution = fileUrl.height
const videoId = isStreamingPlaylist(videoOrPlaylist) ? null : videoOrPlaylist.id
const videoStreamingPlaylistId = isStreamingPlaylist(videoOrPlaylist) ? videoOrPlaylist.id : null
const videoStreamingPlaylistId = isStreamingPlaylist(videoOrPlaylist)
? videoOrPlaylist.id
: null
const { torrentFilename, infoHash, torrentUrl } = getTorrentRelatedInfo({ videoOrPlaylist, urls, fileUrl })
const attribute = {
extname,
infoHash: parsed.infoHash,
resolution,
size: fileUrl.size,
fps: fileUrl.fps || -1,
metadataUrl: metadata?.href,
width: fileUrl.width,
@ -101,9 +91,9 @@ export function getFileAttributesFromUrl (
filename: basename(fileUrl.href),
fileUrl: fileUrl.href,
infoHash,
torrentFilename,
torrentUrl,
// Use our own torrent name since we proxify torrent requests
torrentFilename: generateTorrentFileName(videoOrPlaylist, resolution),
// This is a video file owned by a video or by a streaming playlist
videoId,
@ -126,19 +116,17 @@ export function getStreamingPlaylistAttributesFromObject (video: MVideoId, video
const files: unknown[] = playlistUrlObject.tag.filter(u => isAPVideoUrlObject(u)) as ActivityVideoUrlObject[]
if (!segmentsSha256UrlObject) {
logger.warn('No segment sha256 URL found in AP playlist object.', { playlistUrl: playlistUrlObject })
continue
}
const attribute = {
type: VideoStreamingPlaylistType.HLS,
playlistFilename: basename(playlistUrlObject.href),
playlistUrl: playlistUrlObject.href,
segmentsSha256Filename: basename(segmentsSha256UrlObject.href),
segmentsSha256Url: segmentsSha256UrlObject.href,
segmentsSha256Filename: segmentsSha256UrlObject
? basename(segmentsSha256UrlObject.href)
: null,
segmentsSha256Url: segmentsSha256UrlObject?.href ?? null,
p2pMediaLoaderInfohashes: VideoStreamingPlaylistModel.buildP2PMediaLoaderInfoHashes(playlistUrlObject.href, files),
p2pMediaLoaderPeerVersion: P2P_MEDIA_LOADER_PEER_VERSION,
@ -270,3 +258,41 @@ function isAPMagnetUrlObject (url: any): url is ActivityMagnetUrlObject {
function isAPHashTagObject (url: any): url is ActivityHashTagObject {
return url && url.type === 'Hashtag'
}
function getTorrentRelatedInfo (options: {
videoOrPlaylist: MVideo | MStreamingPlaylistVideo
urls: (ActivityTagObject | ActivityUrlObject)[]
fileUrl: ActivityVideoUrlObject
}) {
const { urls, fileUrl, videoOrPlaylist } = options
// Fetch associated magnet uri
const magnet = urls.filter(isAPMagnetUrlObject)
.find(u => u.height === fileUrl.height)
if (!magnet) {
return {
torrentUrl: null,
torrentFilename: null,
infoHash: null
}
}
const magnetParsed = magnetUriDecode(magnet.href)
if (magnetParsed && isVideoFileInfoHashValid(magnetParsed.infoHash) === false) {
throw new Error('Info hash is not valid in magnet URI ' + magnet.href)
}
const torrentUrl = Array.isArray(magnetParsed.xs)
? magnetParsed.xs[0]
: magnetParsed.xs
return {
torrentUrl,
// Use our own torrent name since we proxify torrent requests
torrentFilename: generateTorrentFileName(videoOrPlaylist, fileUrl.height),
infoHash: magnetParsed.infoHash
}
}

View file

@ -56,6 +56,8 @@ async function getRatesCount (type: 'like' | 'dislike', video: MVideo, fetchedVi
? fetchedVideo.likes
: fetchedVideo.dislikes
if (!uri) return
logger.info('Sync %s of video %s', type, video.url)
const { body } = await fetchAP<ActivityPubOrderedCollection<any>>(uri)
@ -70,6 +72,7 @@ async function getRatesCount (type: 'like' | 'dislike', video: MVideo, fetchedVi
function syncShares (video: MVideo, fetchedVideo: VideoObject, isSync: boolean) {
const uri = fetchedVideo.shares
if (!uri) return
if (!isSync) {
return createJob({ uri, videoId: video.id, type: 'video-shares' })
@ -84,6 +87,7 @@ function syncShares (video: MVideo, fetchedVideo: VideoObject, isSync: boolean)
function syncComments (video: MVideo, fetchedVideo: VideoObject, isSync: boolean) {
const uri = fetchedVideo.comments
if (!uri) return
if (!isSync) {
return createJob({ uri, videoId: video.id, type: 'video-comments' })