Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
764e41f2b7
|
||
|
|
84cd880753
|
||
|
|
20c52a51ae
|
||
|
|
6b93ac0d78
|
||
|
|
e0673b084b
|
+7
-1
@@ -129,7 +129,6 @@ func transitionToOfflineVideoStreamContent() {
|
||||
if err != nil {
|
||||
log.Errorln("unable to create master playlist:", err)
|
||||
} else {
|
||||
defer masterFile.Close()
|
||||
_, _ = masterFile.WriteString("#EXTM3U\n")
|
||||
_, _ = masterFile.WriteString("#EXT-X-VERSION:7\n")
|
||||
_, _ = masterFile.WriteString("#EXT-X-INDEPENDENT-SEGMENTS\n")
|
||||
@@ -137,6 +136,13 @@ func transitionToOfflineVideoStreamContent() {
|
||||
_, _ = fmt.Fprintf(masterFile, "#EXT-X-STREAM-INF:BANDWIDTH=0\n")
|
||||
_, _ = fmt.Fprintf(masterFile, "%d/stream.m3u8\n", index)
|
||||
}
|
||||
if err := masterFile.Close(); err != nil {
|
||||
log.Errorln("unable to close master playlist:", err)
|
||||
}
|
||||
|
||||
// Notify the storage provider so it can rewrite variant URLs
|
||||
// to absolute paths for S3 or remote serving endpoints.
|
||||
_storage.MasterPlaylistWritten(masterPlaylistPath)
|
||||
}
|
||||
|
||||
// Copy the logo to be the thumbnail
|
||||
|
||||
@@ -112,7 +112,9 @@ func saveOfflineFMP4ToDisk() (initPath string, segmentPath string, err error) {
|
||||
return "", "", fmt.Errorf("unable to write offline init segment to disk: %s", err)
|
||||
}
|
||||
|
||||
initTmp.Close()
|
||||
if err := initTmp.Close(); err != nil {
|
||||
return "", "", fmt.Errorf("unable to close offline init segment: %s", err)
|
||||
}
|
||||
initPath, _ = filepath.Abs(initTmp.Name())
|
||||
|
||||
segData := static.GetOfflineMediaSegment()
|
||||
@@ -125,7 +127,9 @@ func saveOfflineFMP4ToDisk() (initPath string, segmentPath string, err error) {
|
||||
return "", "", fmt.Errorf("unable to write offline media segment to disk: %s", err)
|
||||
}
|
||||
|
||||
segTmp.Close()
|
||||
if err := segTmp.Close(); err != nil {
|
||||
return "", "", fmt.Errorf("unable to close offline media segment: %s", err)
|
||||
}
|
||||
segmentPath, _ = filepath.Abs(segTmp.Name())
|
||||
|
||||
return initPath, segmentPath, nil
|
||||
|
||||
@@ -82,7 +82,7 @@ func getAllFilesRecursive(baseDirectory string) (map[string][]os.FileInfo, error
|
||||
directory = info.Name()
|
||||
}
|
||||
|
||||
if filepath.Ext(info.Name()) == ".m4s" || filepath.Ext(info.Name()) == ".mp4" {
|
||||
if filepath.Ext(info.Name()) == ".m4s" {
|
||||
files[directory] = append(files[directory], info)
|
||||
}
|
||||
|
||||
|
||||
@@ -317,7 +317,7 @@ func (s *S3Storage) retrieveAllVideoSegments() ([]s3object, error) {
|
||||
err := s.s3Client.ListObjectsPages(allObjectsListRequest,
|
||||
func(page *s3.ListObjectsOutput, lastPage bool) bool {
|
||||
for _, item := range page.Contents {
|
||||
if strings.HasSuffix(*item.Key, ".m4s") || strings.HasSuffix(*item.Key, ".mp4") {
|
||||
if strings.HasSuffix(*item.Key, ".m4s") {
|
||||
allObjects = append(allObjects, s3object{
|
||||
key: *item.Key,
|
||||
lastModified: *item.LastModified,
|
||||
|
||||
@@ -89,8 +89,19 @@ func fireThumbnailGenerator(segmentPath string, variantIndex int) error {
|
||||
return nil
|
||||
}
|
||||
configRepository := configrepository.Get()
|
||||
initSegment := path.Join(framePath, "init.mp4")
|
||||
// With multiple variants ffmpeg names init segments init_0.mp4, init_1.mp4, etc.
|
||||
// With a single variant it uses init.mp4.
|
||||
initSegment := path.Join(framePath, fmt.Sprintf("init_%d.mp4", variantIndex))
|
||||
if !utils.DoesFileExists(initSegment) {
|
||||
initSegment = path.Join(framePath, "init.mp4")
|
||||
}
|
||||
mostRecentFile := path.Join(framePath, names[0])
|
||||
|
||||
// The segment may have been cleaned up between ReadDir and now.
|
||||
if !utils.DoesFileExists(mostRecentFile) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// fMP4 segments require the init segment to be readable by ffmpeg
|
||||
inputArg := fmt.Sprintf("concat:%s|%s", initSegment, mostRecentFile)
|
||||
ffmpegPath := utils.ValidatedFfmpegPath(configRepository.GetFfMpegPath())
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+12
-10
@@ -215,23 +215,25 @@ func GetCacheDurationSecondsForPath(filePath string) int {
|
||||
|
||||
defaultDaysCached := 30
|
||||
|
||||
if filename == "thumbnail.jpg" || filename == "preview.gif" {
|
||||
if filename == "thumbnail.jpg" || filename == "preview.gif" || filename == "init.mp4" {
|
||||
// Thumbnails & preview gif re-generate during live
|
||||
return 20
|
||||
} else if fileExtension == ".js" || fileExtension == ".css" {
|
||||
// Cache javascript & CSS
|
||||
return 60 * 60 * 24 * defaultDaysCached
|
||||
} else if fileExtension == ".m4s" || fileExtension == ".mp4" || fileExtension == ".woff2" {
|
||||
}
|
||||
|
||||
if filename == "/" || fileExtension == "" {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch fileExtension {
|
||||
case ".m3u8", ".html":
|
||||
return 0
|
||||
case ".m4s", ".mp4", ".woff2":
|
||||
// Cache video segments as long as you want. They can't change.
|
||||
// This matters most for local hosting of segments for recordings
|
||||
// and not for live or 3rd party storage.
|
||||
return 31557600
|
||||
} else if fileExtension == ".m3u8" {
|
||||
return 0
|
||||
} else if fileExtension == ".jpg" || fileExtension == ".png" || fileExtension == ".gif" || fileExtension == ".svg" {
|
||||
case ".js", ".css", ".jpg", ".png", ".gif", ".svg":
|
||||
return 60 * 60 * 24 * defaultDaysCached
|
||||
} else if fileExtension == ".html" || filename == "/" || fileExtension == "" {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Default cache length in seconds
|
||||
|
||||
Reference in New Issue
Block a user