mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-02-25 18:55:32 -06:00
Add hls support on server
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { ActivityVideoUrlObject } from './common-objects'
|
||||
import { ActivityVideoUrlObject, ActivityPlaylistUrlObject } from './common-objects'
|
||||
|
||||
export interface CacheFileObject {
|
||||
id: string
|
||||
type: 'CacheFile',
|
||||
object: string
|
||||
expires: string
|
||||
url: ActivityVideoUrlObject
|
||||
url: ActivityVideoUrlObject | ActivityPlaylistUrlObject
|
||||
}
|
||||
|
||||
@@ -28,25 +28,47 @@ export type ActivityVideoUrlObject = {
|
||||
fps: number
|
||||
}
|
||||
|
||||
export type ActivityUrlObject =
|
||||
ActivityVideoUrlObject
|
||||
|
|
||||
{
|
||||
type: 'Link'
|
||||
// TODO: remove mimeType (backward compatibility, introduced in v1.1.0)
|
||||
mimeType?: 'application/x-bittorrent' | 'application/x-bittorrent;x-scheme-handler/magnet'
|
||||
mediaType: 'application/x-bittorrent' | 'application/x-bittorrent;x-scheme-handler/magnet'
|
||||
href: string
|
||||
height: number
|
||||
}
|
||||
|
|
||||
{
|
||||
type: 'Link'
|
||||
// TODO: remove mimeType (backward compatibility, introduced in v1.1.0)
|
||||
mimeType?: 'text/html'
|
||||
mediaType: 'text/html'
|
||||
href: string
|
||||
}
|
||||
export type ActivityPlaylistSegmentHashesObject = {
|
||||
type: 'Link'
|
||||
name: 'sha256'
|
||||
// TODO: remove mimeType (backward compatibility, introduced in v1.1.0)
|
||||
mimeType?: 'application/json'
|
||||
mediaType: 'application/json'
|
||||
href: string
|
||||
}
|
||||
|
||||
export type ActivityPlaylistInfohashesObject = {
|
||||
type: 'Infohash'
|
||||
name: string
|
||||
}
|
||||
|
||||
export type ActivityPlaylistUrlObject = {
|
||||
type: 'Link'
|
||||
// TODO: remove mimeType (backward compatibility, introduced in v1.1.0)
|
||||
mimeType?: 'application/x-mpegURL'
|
||||
mediaType: 'application/x-mpegURL'
|
||||
href: string
|
||||
tag?: (ActivityPlaylistSegmentHashesObject | ActivityPlaylistInfohashesObject)[]
|
||||
}
|
||||
|
||||
export type ActivityBitTorrentUrlObject = {
|
||||
type: 'Link'
|
||||
// TODO: remove mimeType (backward compatibility, introduced in v1.1.0)
|
||||
mimeType?: 'application/x-bittorrent' | 'application/x-bittorrent;x-scheme-handler/magnet'
|
||||
mediaType: 'application/x-bittorrent' | 'application/x-bittorrent;x-scheme-handler/magnet'
|
||||
href: string
|
||||
height: number
|
||||
}
|
||||
|
||||
export type ActivityHtmlUrlObject = {
|
||||
type: 'Link'
|
||||
// TODO: remove mimeType (backward compatibility, introduced in v1.1.0)
|
||||
mimeType?: 'text/html'
|
||||
mediaType: 'text/html'
|
||||
href: string
|
||||
}
|
||||
|
||||
export type ActivityUrlObject = ActivityVideoUrlObject | ActivityPlaylistUrlObject | ActivityBitTorrentUrlObject | ActivityHtmlUrlObject
|
||||
|
||||
export interface ActivityPubAttributedTo {
|
||||
type: 'Group' | 'Person'
|
||||
|
||||
@@ -61,6 +61,9 @@ export interface CustomConfig {
|
||||
'720p': boolean
|
||||
'1080p': boolean
|
||||
}
|
||||
hls: {
|
||||
enabled: boolean
|
||||
}
|
||||
}
|
||||
|
||||
import: {
|
||||
|
||||
@@ -25,11 +25,15 @@ export interface ServerConfig {
|
||||
|
||||
signup: {
|
||||
allowed: boolean,
|
||||
allowedForCurrentIP: boolean,
|
||||
allowedForCurrentIP: boolean
|
||||
requiresEmailVerification: boolean
|
||||
}
|
||||
|
||||
transcoding: {
|
||||
hls: {
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
enabledResolutions: number[]
|
||||
}
|
||||
|
||||
@@ -48,7 +52,7 @@ export interface ServerConfig {
|
||||
file: {
|
||||
size: {
|
||||
max: number
|
||||
},
|
||||
}
|
||||
extensions: string[]
|
||||
}
|
||||
}
|
||||
|
||||
12
shared/models/videos/video-streaming-playlist.model.ts
Normal file
12
shared/models/videos/video-streaming-playlist.model.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { VideoStreamingPlaylistType } from './video-streaming-playlist.type'
|
||||
|
||||
export class VideoStreamingPlaylist {
|
||||
id: number
|
||||
type: VideoStreamingPlaylistType
|
||||
playlistUrl: string
|
||||
segmentsSha256Url: string
|
||||
|
||||
redundancies: {
|
||||
baseUrl: string
|
||||
}[]
|
||||
}
|
||||
3
shared/models/videos/video-streaming-playlist.type.ts
Normal file
3
shared/models/videos/video-streaming-playlist.type.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export enum VideoStreamingPlaylistType {
|
||||
HLS = 1
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { VideoChannel } from './channel/video-channel.model'
|
||||
import { VideoPrivacy } from './video-privacy.enum'
|
||||
import { VideoScheduleUpdate } from './video-schedule-update.model'
|
||||
import { VideoConstant } from './video-constant.model'
|
||||
import { VideoStreamingPlaylist } from './video-streaming-playlist.model'
|
||||
|
||||
export interface VideoFile {
|
||||
magnetUri: string
|
||||
@@ -86,4 +87,8 @@ export interface VideoDetails extends Video {
|
||||
// Not optional in details (unlike in Video)
|
||||
waitTranscoding: boolean
|
||||
state: VideoConstant<VideoState>
|
||||
|
||||
trackerUrls: string[]
|
||||
|
||||
streamingPlaylists: VideoStreamingPlaylist[]
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ export * from './users/users'
|
||||
export * from './videos/video-abuses'
|
||||
export * from './videos/video-blacklist'
|
||||
export * from './videos/video-channels'
|
||||
export * from './videos/video-comments'
|
||||
export * from './videos/video-playlists'
|
||||
export * from './videos/videos'
|
||||
export * from './videos/video-change-ownership'
|
||||
export * from './feeds/feeds'
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import * as request from 'supertest'
|
||||
import { buildAbsoluteFixturePath, root } from '../miscs/miscs'
|
||||
import { isAbsolute, join } from 'path'
|
||||
import { parse } from 'url'
|
||||
|
||||
function makeRawRequest (url: string, statusCodeExpected?: number) {
|
||||
const { host, protocol, pathname } = parse(url)
|
||||
|
||||
return makeGetRequest({ url: `${protocol}//${host}`, path: pathname, statusCodeExpected })
|
||||
}
|
||||
|
||||
function makeGetRequest (options: {
|
||||
url: string,
|
||||
path: string,
|
||||
path?: string,
|
||||
query?: any,
|
||||
token?: string,
|
||||
statusCodeExpected?: number,
|
||||
@@ -13,8 +20,7 @@ function makeGetRequest (options: {
|
||||
if (!options.statusCodeExpected) options.statusCodeExpected = 400
|
||||
if (options.contentType === undefined) options.contentType = 'application/json'
|
||||
|
||||
const req = request(options.url)
|
||||
.get(options.path)
|
||||
const req = request(options.url).get(options.path)
|
||||
|
||||
if (options.contentType) req.set('Accept', options.contentType)
|
||||
if (options.token) req.set('Authorization', 'Bearer ' + options.token)
|
||||
@@ -164,5 +170,6 @@ export {
|
||||
makePostBodyRequest,
|
||||
makePutBodyRequest,
|
||||
makeDeleteRequest,
|
||||
makeRawRequest,
|
||||
updateAvatarRequest
|
||||
}
|
||||
|
||||
@@ -97,6 +97,9 @@ function updateCustomSubConfig (url: string, token: string, newConfig: any) {
|
||||
'480p': true,
|
||||
'720p': false,
|
||||
'1080p': false
|
||||
},
|
||||
hls: {
|
||||
enabled: false
|
||||
}
|
||||
},
|
||||
import: {
|
||||
|
||||
@@ -166,9 +166,13 @@ async function reRunServer (server: ServerInfo, configOverride?: any) {
|
||||
}
|
||||
|
||||
async function checkTmpIsEmpty (server: ServerInfo) {
|
||||
return checkDirectoryIsEmpty(server, 'tmp')
|
||||
}
|
||||
|
||||
async function checkDirectoryIsEmpty (server: ServerInfo, directory: string) {
|
||||
const testDirectory = 'test' + server.serverNumber
|
||||
|
||||
const directoryPath = join(root(), testDirectory, 'tmp')
|
||||
const directoryPath = join(root(), testDirectory, directory)
|
||||
|
||||
const directoryExists = existsSync(directoryPath)
|
||||
expect(directoryExists).to.be.true
|
||||
@@ -199,6 +203,7 @@ async function waitUntilLog (server: ServerInfo, str: string, count = 1) {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
checkDirectoryIsEmpty,
|
||||
checkTmpIsEmpty,
|
||||
ServerInfo,
|
||||
flushAndRunMultipleServers,
|
||||
|
||||
21
shared/utils/videos/video-playlists.ts
Normal file
21
shared/utils/videos/video-playlists.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { makeRawRequest } from '../requests/requests'
|
||||
|
||||
function getPlaylist (url: string, statusCodeExpected = 200) {
|
||||
return makeRawRequest(url, statusCodeExpected)
|
||||
}
|
||||
|
||||
function getSegment (url: string, statusCodeExpected = 200) {
|
||||
return makeRawRequest(url, statusCodeExpected)
|
||||
}
|
||||
|
||||
function getSegmentSha256 (url: string, statusCodeExpected = 200) {
|
||||
return makeRawRequest(url, statusCodeExpected)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
getPlaylist,
|
||||
getSegment,
|
||||
getSegmentSha256
|
||||
}
|
||||
@@ -271,7 +271,16 @@ function removeVideo (url: string, token: string, id: number | string, expectedS
|
||||
async function checkVideoFilesWereRemoved (
|
||||
videoUUID: string,
|
||||
serverNumber: number,
|
||||
directories = [ 'redundancy', 'videos', 'thumbnails', 'torrents', 'previews', 'captions' ]
|
||||
directories = [
|
||||
'redundancy',
|
||||
'videos',
|
||||
'thumbnails',
|
||||
'torrents',
|
||||
'previews',
|
||||
'captions',
|
||||
join('playlists', 'hls'),
|
||||
join('redundancy', 'hls')
|
||||
]
|
||||
) {
|
||||
const testDirectory = 'test' + serverNumber
|
||||
|
||||
@@ -279,7 +288,7 @@ async function checkVideoFilesWereRemoved (
|
||||
const directoryPath = join(root(), testDirectory, directory)
|
||||
|
||||
const directoryExists = existsSync(directoryPath)
|
||||
expect(directoryExists).to.be.true
|
||||
if (!directoryExists) continue
|
||||
|
||||
const files = await readdir(directoryPath)
|
||||
for (const file of files) {
|
||||
|
||||
Reference in New Issue
Block a user