Add hls support on server

This commit is contained in:
Chocobozzz
2019-01-29 08:37:25 +01:00
committed by Chocobozzz
parent 4348a27d25
commit 0920929696
81 changed files with 2000 additions and 407 deletions

View File

@@ -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
}

View File

@@ -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'

View File

@@ -61,6 +61,9 @@ export interface CustomConfig {
'720p': boolean
'1080p': boolean
}
hls: {
enabled: boolean
}
}
import: {

View File

@@ -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[]
}
}

View 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
}[]
}

View File

@@ -0,0 +1,3 @@
export enum VideoStreamingPlaylistType {
HLS = 1
}

View File

@@ -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[]
}

View File

@@ -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'

View File

@@ -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
}

View File

@@ -97,6 +97,9 @@ function updateCustomSubConfig (url: string, token: string, newConfig: any) {
'480p': true,
'720p': false,
'1080p': false
},
hls: {
enabled: false
}
},
import: {

View File

@@ -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,

View 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
}

View File

@@ -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) {