Listing videos nom+liens

Bonjour,
Tout d’abord bravo pour cet excellent travail.
Je voulais savoir s’il était possible d’obtenir un listing de toutes les vidéos contenues sur mon instance peertube avec leur nom et les liens de partage?

J’ai bien vue l’astuce de l’API:
https://monsite.tld/api/v1/videos?start=0&count=100&isLocal=true
Mais je n’obtiens pas toutes les videos?

D’avance merci pour l’aide apportée sur ce sujet.
Cordialement,

Bonjour et merci :slight_smile:

Mais je n’obtiens pas toutes les videos?

Il faut passer ensuite à la page suivante: https://monsite.tld/api/v1/videos?start=100&count=100&isLocal=true

Hello,

Alors, pour avoir toutes les vidéos, il manque:

  • le fait de boucler pour récupérer toutes les pages
  • le fait d’être identifié avec un compte administrateur pour avoir accès aux vidéos non publiques

Voilà un bout de code en Typescript (écrit un peu à l’arrache), qui peut servir de base:

import type { Video } from '@peertube/peertube-types'
import prompt from 'prompt'
import { got } from 'got'

const peertubeUrl = 'https://videos.example.com/'
const peertubeUsername = 'root'
const nbVideoPerRequest = 100

async function run (): Promise<void> {
  const password = await getPassword()
  const authent = await getAuthent(password)
  
  let videos = await listAllVideos(authent)
  for (const video of videos) {
    console.log(video.uuid + ': ', video.description)
  }

}

function getPassword (): Promise<string> {
  return new Promise((resolve, reject) => {
    prompt.start()
    prompt.get({
      properties: {
        password: {
          hidden: true
        }
      }
    }, (err: any, result: any) => {
      if (err) {
        reject(err)
      } else {
        resolve(result.password)
      }
    })
  })
}

interface Authent {
  client: {
    client_id: string
    client_secret: string
  }
  token: {
    access_token: string
    token_type: string
    expires_in: number
    refresh_token: string
  }
}

async function getAuthent(password: string): Promise<Authent> {
  // Get Client
  console.log('Getting client...')
  const client = await got.get(peertubeUrl + 'api/v1/oauth-clients/local').json() as Authent['client']
  console.log('Getting token...')
  const token = await got.post(peertubeUrl + 'api/v1/users/token', {
    form: {
      client_id: client.client_id,
      client_secret: client.client_secret,
      username: peertubeUsername,
      password: password,
      grant_type: 'password',
      response_type: 'code'
    }
  }).json() as Authent['token']
  return { client, token }
}

async function listAllVideos(authent: Authent): Promise<Video[]> {
  const result: Video[] = []
  while (true) {
    const videos = await listVideos(authent, result.length)
    result.push(...videos)
    if (videos.length < nbVideoPerRequest) {
      break
    }
  }
  return result
}

async function listVideos(authent: Authent, start: number): Promise<Video[]> {
  console.log('Getting video from start=' + start)

  const searchParams = new URLSearchParams()
  searchParams.append('count', nbVideoPerRequest.toString())
  searchParams.append('start', start.toString())
  searchParams.append('isLocal', '1')
  searchParams.append('sort',  'createdAt')
  searchParams.append('privacyOneOf', '1')
  searchParams.append('privacyOneOf', '2')
  searchParams.append('privacyOneOf', '3')
  searchParams.append('privacyOneOf', '4')
  searchParams.append('privacyOneOf', '5')
  searchParams.append('include', '1')

  const result = await got.get(peertubeUrl + 'api/v1/videos', {
    headers: {
      Authorization: 'Bearer ' + authent.token.access_token
    },
    searchParams
  }).json() as any
  return result.data as Video[]
}

run().then(
  () => console.info('Done'),
  (err) => console.error(err)
)

Il y a des constantes au début pour définir l’url de l’instance et le compte à utiliser.
Le password sera demandé par un prompt (pour éviter de l’avoir stocké en clair quelquepart).

Le fichier package.json qui va avec (écrit complètement à l’arrache, mais ce qui compte c’est les dépendances):

{
  "type": "module",
  "name": "peertube-custom-cli",
  "version": "1.0.0",
  "description": "",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "AGPL-v3",
  "dependencies": {
    "@tsconfig/node18": "^18.2.3",
    "commander": "^12.0.0",
    "got": "^14.2.1",
    "prompt": "^1.3.0",
    "typescript": "^5.4.3"
  },
  "devDependencies": {
    "@peertube/peertube-types": "^6.0.3",
    "@types/node": "^20.11.30",
    "@types/prompt": "^1.1.8"
  }
}

Le fichier package.json est à mettre à la racine d’un nouveau dossier.
Le fichier typescript est à mettre sous src/index.ts.

Pour installer les dépendances: npm install
Pour compiler: npm run build
Puis pour lancer: node .

Petite précision sur les paramètres additionnels que j’ai mis:

  • privacyOneOf: liste les différents mode « publique », « privée », …
  • include: permet aussi d’avoir les vidéos qui ne sont pas encore publiées. D’autres valeurs sont possibles, cf PeerTube

Merci, mais ça ne fonctionne pas, est-ce que c’est parce que ces vidéos ne sont pas « publiées »?

Oui sûrement, du coup plutôt utiliser la méthode de @JohnLivingston :slight_smile:

Merci, je vais essayer.

Bonjour JohnLivingston,
Merci beaucoup je vais regarder de ce côté là.