mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-03 09:49:20 +02:00
Always specify s3 content type
This commit is contained in:
parent
fb9d678f7f
commit
4739b117e8
7 changed files with 57 additions and 36 deletions
|
@ -1368,7 +1368,7 @@ function buildVideoMimetypeExt () {
|
||||||
|
|
||||||
// The standard video format used by many Sony and Panasonic HD camcorders.
|
// The standard video format used by many Sony and Panasonic HD camcorders.
|
||||||
// It is also used for storing high definition video on Blu-ray discs.
|
// It is also used for storing high definition video on Blu-ray discs.
|
||||||
'video/mp2t': '.mts',
|
'video/mp2t': [ '.mts', 'ts' ],
|
||||||
'video/vnd.dlna.mpeg-tts': '.mts',
|
'video/vnd.dlna.mpeg-tts': '.mts',
|
||||||
|
|
||||||
'video/m2ts': '.m2ts',
|
'video/m2ts': '.m2ts',
|
||||||
|
|
|
@ -144,8 +144,7 @@ function updateMasterHLSPlaylist (video: MVideo, playlistArg: MStreamingPlaylist
|
||||||
playlist.playlistUrl = await storeHLSFileFromContent({
|
playlist.playlistUrl = await storeHLSFileFromContent({
|
||||||
playlist,
|
playlist,
|
||||||
pathOrFilename: playlist.playlistFilename,
|
pathOrFilename: playlist.playlistFilename,
|
||||||
content: masterPlaylistContent,
|
content: masterPlaylistContent
|
||||||
contentType: 'application/x-mpegurl; charset=utf-8'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
logger.info(`Updated master playlist file of video ${video.uuid} to object storage ${playlist.playlistUrl}`, lTags(video.uuid))
|
logger.info(`Updated master playlist file of video ${video.uuid} to object storage ${playlist.playlistUrl}`, lTags(video.uuid))
|
||||||
|
@ -202,8 +201,7 @@ function updateSha256VODSegments (video: MVideo, playlistArg: MStreamingPlaylist
|
||||||
playlist.segmentsSha256Url = await storeHLSFileFromContent({
|
playlist.segmentsSha256Url = await storeHLSFileFromContent({
|
||||||
playlist,
|
playlist,
|
||||||
pathOrFilename: playlist.segmentsSha256Filename,
|
pathOrFilename: playlist.segmentsSha256Filename,
|
||||||
content: JSON.stringify(json),
|
content: JSON.stringify(json)
|
||||||
contentType: 'application/json; charset=utf-8'
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const outputPath = VideoPathManager.Instance.getFSHLSOutputPath(video, playlist.segmentsSha256Filename)
|
const outputPath = VideoPathManager.Instance.getFSHLSOutputPath(video, playlist.segmentsSha256Filename)
|
||||||
|
|
|
@ -122,8 +122,7 @@ async function moveCaptionFiles (captions: MVideoCaption[], hls: MStreamingPlayl
|
||||||
caption.m3u8Url = await storeHLSFileFromContent({
|
caption.m3u8Url = await storeHLSFileFromContent({
|
||||||
playlist: hls,
|
playlist: hls,
|
||||||
pathOrFilename: caption.m3u8Filename,
|
pathOrFilename: caption.m3u8Filename,
|
||||||
content,
|
content
|
||||||
contentType: 'application/vnd.apple.mpegurl; charset=utf-8'
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await caption.save()
|
await caption.save()
|
||||||
|
|
|
@ -229,8 +229,7 @@ class MuxingSession extends EventEmitter implements MuxingSession {
|
||||||
{
|
{
|
||||||
playlist: this.streamingPlaylist,
|
playlist: this.streamingPlaylist,
|
||||||
pathOrFilename: this.streamingPlaylist.playlistFilename,
|
pathOrFilename: this.streamingPlaylist.playlistFilename,
|
||||||
content: masterContent,
|
content: masterContent
|
||||||
contentType: 'application/x-mpegurl; charset=utf-8'
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -419,8 +418,7 @@ class MuxingSession extends EventEmitter implements MuxingSession {
|
||||||
storeHLSFileFromContent({
|
storeHLSFileFromContent({
|
||||||
playlist: this.streamingPlaylist,
|
playlist: this.streamingPlaylist,
|
||||||
pathOrFilename: m3u8Path,
|
pathOrFilename: m3u8Path,
|
||||||
content: filteredPlaylistContent,
|
content: filteredPlaylistContent
|
||||||
contentType: 'application/x-mpegurl; charset=utf-8'
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -50,8 +50,7 @@ async function storeObject (options: {
|
||||||
objectStorageKey: string
|
objectStorageKey: string
|
||||||
bucketInfo: BucketInfo
|
bucketInfo: BucketInfo
|
||||||
isPrivate: boolean
|
isPrivate: boolean
|
||||||
|
contentType: string
|
||||||
contentType?: string
|
|
||||||
}): Promise<string> {
|
}): Promise<string> {
|
||||||
const { inputPath, objectStorageKey, bucketInfo, isPrivate, contentType } = options
|
const { inputPath, objectStorageKey, bucketInfo, isPrivate, contentType } = options
|
||||||
|
|
||||||
|
@ -67,8 +66,7 @@ async function storeContent (options: {
|
||||||
objectStorageKey: string
|
objectStorageKey: string
|
||||||
bucketInfo: BucketInfo
|
bucketInfo: BucketInfo
|
||||||
isPrivate: boolean
|
isPrivate: boolean
|
||||||
|
contentType: string
|
||||||
contentType?: string
|
|
||||||
}): Promise<string> {
|
}): Promise<string> {
|
||||||
const { content, objectStorageKey, bucketInfo, isPrivate, contentType } = options
|
const { content, objectStorageKey, bucketInfo, isPrivate, contentType } = options
|
||||||
|
|
||||||
|
@ -82,8 +80,7 @@ async function storeStream (options: {
|
||||||
objectStorageKey: string
|
objectStorageKey: string
|
||||||
bucketInfo: BucketInfo
|
bucketInfo: BucketInfo
|
||||||
isPrivate: boolean
|
isPrivate: boolean
|
||||||
|
contentType: string
|
||||||
contentType?: string
|
|
||||||
}): Promise<string> {
|
}): Promise<string> {
|
||||||
const { stream, objectStorageKey, bucketInfo, isPrivate, contentType } = options
|
const { stream, objectStorageKey, bucketInfo, isPrivate, contentType } = options
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ export function storeUserExportFile (stream: Readable, userExport: MUserExport)
|
||||||
stream,
|
stream,
|
||||||
objectStorageKey: generateUserExportObjectStorageKey(userExport.filename),
|
objectStorageKey: generateUserExportObjectStorageKey(userExport.filename),
|
||||||
bucketInfo: CONFIG.OBJECT_STORAGE.USER_EXPORTS,
|
bucketInfo: CONFIG.OBJECT_STORAGE.USER_EXPORTS,
|
||||||
isPrivate: true
|
isPrivate: true,
|
||||||
|
contentType: 'application/zip'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { logger } from '@server/helpers/logger.js'
|
||||||
import { CONFIG } from '@server/initializers/config.js'
|
import { CONFIG } from '@server/initializers/config.js'
|
||||||
import { MStreamingPlaylistVideo, MStreamingPlaylistVideoUUID, MVideo, MVideoCaption, MVideoFile } from '@server/types/models/index.js'
|
import { MStreamingPlaylistVideo, MStreamingPlaylistVideoUUID, MVideo, MVideoCaption, MVideoFile } from '@server/types/models/index.js'
|
||||||
import { MVideoSource } from '@server/types/models/video/video-source.js'
|
import { MVideoSource } from '@server/types/models/video/video-source.js'
|
||||||
import { basename, join } from 'path'
|
import { basename, extname, join } from 'path'
|
||||||
import { getHLSDirectory } from '../paths.js'
|
import { getHLSDirectory } from '../paths.js'
|
||||||
import { VideoPathManager } from '../video-path-manager.js'
|
import { VideoPathManager } from '../video-path-manager.js'
|
||||||
import {
|
import {
|
||||||
|
@ -25,6 +25,7 @@ import {
|
||||||
updateObjectACL,
|
updateObjectACL,
|
||||||
updatePrefixACL
|
updatePrefixACL
|
||||||
} from './shared/index.js'
|
} from './shared/index.js'
|
||||||
|
import { MIMETYPES } from '@server/initializers/constants.js'
|
||||||
|
|
||||||
export function listHLSFileKeysOf (playlist: MStreamingPlaylistVideo) {
|
export function listHLSFileKeysOf (playlist: MStreamingPlaylistVideo) {
|
||||||
return listKeysOfPrefix(generateHLSObjectBaseStorageKey(playlist), CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS)
|
return listKeysOfPrefix(generateHLSObjectBaseStorageKey(playlist), CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS)
|
||||||
|
@ -37,35 +38,38 @@ export function storeHLSFileFromFilename (playlist: MStreamingPlaylistVideo, fil
|
||||||
inputPath: join(getHLSDirectory(playlist.Video), filename),
|
inputPath: join(getHLSDirectory(playlist.Video), filename),
|
||||||
objectStorageKey: generateHLSObjectStorageKey(playlist, filename),
|
objectStorageKey: generateHLSObjectStorageKey(playlist, filename),
|
||||||
bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS,
|
bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS,
|
||||||
isPrivate: playlist.Video.hasPrivateStaticPath()
|
isPrivate: playlist.Video.hasPrivateStaticPath(),
|
||||||
|
contentType: getObjectStorageContentType(filename)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function storeHLSFileFromPath (playlist: MStreamingPlaylistVideo, path: string) {
|
export function storeHLSFileFromPath (playlist: MStreamingPlaylistVideo, path: string) {
|
||||||
|
const filename = basename(path)
|
||||||
|
|
||||||
return storeObject({
|
return storeObject({
|
||||||
inputPath: path,
|
inputPath: path,
|
||||||
objectStorageKey: generateHLSObjectStorageKey(playlist, basename(path)),
|
objectStorageKey: generateHLSObjectStorageKey(playlist, filename),
|
||||||
bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS,
|
bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS,
|
||||||
isPrivate: playlist.Video.hasPrivateStaticPath()
|
isPrivate: playlist.Video.hasPrivateStaticPath(),
|
||||||
|
contentType: getObjectStorageContentType(filename)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function storeHLSFileFromContent (
|
export function storeHLSFileFromContent (options: {
|
||||||
options: {
|
playlist: MStreamingPlaylistVideo
|
||||||
playlist: MStreamingPlaylistVideo
|
pathOrFilename: string
|
||||||
pathOrFilename: string
|
content: string
|
||||||
content: string
|
}) {
|
||||||
contentType: string
|
const { playlist, pathOrFilename, content } = options
|
||||||
}
|
|
||||||
) {
|
const filename = basename(pathOrFilename)
|
||||||
const { playlist, pathOrFilename, content, contentType } = options
|
|
||||||
|
|
||||||
return storeContent({
|
return storeContent({
|
||||||
content,
|
content,
|
||||||
objectStorageKey: generateHLSObjectStorageKey(playlist, basename(pathOrFilename)),
|
objectStorageKey: generateHLSObjectStorageKey(playlist, filename),
|
||||||
bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS,
|
bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS,
|
||||||
isPrivate: playlist.Video.hasPrivateStaticPath(),
|
isPrivate: playlist.Video.hasPrivateStaticPath(),
|
||||||
contentType
|
contentType: getObjectStorageContentType(filename)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +80,8 @@ export function storeWebVideoFile (video: MVideo, file: MVideoFile) {
|
||||||
inputPath: VideoPathManager.Instance.getFSVideoFileOutputPath(video, file),
|
inputPath: VideoPathManager.Instance.getFSVideoFileOutputPath(video, file),
|
||||||
objectStorageKey: generateWebVideoObjectStorageKey(file.filename),
|
objectStorageKey: generateWebVideoObjectStorageKey(file.filename),
|
||||||
bucketInfo: CONFIG.OBJECT_STORAGE.WEB_VIDEOS,
|
bucketInfo: CONFIG.OBJECT_STORAGE.WEB_VIDEOS,
|
||||||
isPrivate: video.hasPrivateStaticPath()
|
isPrivate: video.hasPrivateStaticPath(),
|
||||||
|
contentType: getObjectStorageContentType(file.filename)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +93,7 @@ export function storeVideoCaption (inputPath: string, filename: string) {
|
||||||
objectStorageKey: generateCaptionObjectStorageKey(filename),
|
objectStorageKey: generateCaptionObjectStorageKey(filename),
|
||||||
bucketInfo: CONFIG.OBJECT_STORAGE.CAPTIONS,
|
bucketInfo: CONFIG.OBJECT_STORAGE.CAPTIONS,
|
||||||
isPrivate: false,
|
isPrivate: false,
|
||||||
contentType: 'text/vtt; charset=UTF-8'
|
contentType: getObjectStorageContentType(filename)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +104,8 @@ export function storeOriginalVideoFile (inputPath: string, filename: string) {
|
||||||
inputPath,
|
inputPath,
|
||||||
objectStorageKey: generateOriginalVideoObjectStorageKey(filename),
|
objectStorageKey: generateOriginalVideoObjectStorageKey(filename),
|
||||||
bucketInfo: CONFIG.OBJECT_STORAGE.ORIGINAL_VIDEO_FILES,
|
bucketInfo: CONFIG.OBJECT_STORAGE.ORIGINAL_VIDEO_FILES,
|
||||||
isPrivate: true
|
isPrivate: true,
|
||||||
|
contentType: getObjectStorageContentType(filename)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,3 +285,25 @@ export function getCaptionReadStream (options: {
|
||||||
rangeHeader
|
rangeHeader
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Private
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function getObjectStorageContentType (filename: string) {
|
||||||
|
if (filename.endsWith('.m3u8')) {
|
||||||
|
return 'application/x-mpegURL; charset=utf-8'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename.endsWith('.json')) {
|
||||||
|
return 'application/json; charset=utf-8'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename.endsWith('.vtt')) {
|
||||||
|
return 'text/vtt; charset=utf-8'
|
||||||
|
}
|
||||||
|
|
||||||
|
const ext = extname(filename).toLowerCase()
|
||||||
|
|
||||||
|
return MIMETYPES.VIDEO.EXT_MIMETYPE[ext] || MIMETYPES.AUDIO.EXT_MIMETYPE[ext]
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue