123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- package core
- import (
- "fmt"
- "os"
- "path/filepath"
- "github.com/grafov/m3u8"
- "github.com/owncast/owncast/config"
- "github.com/owncast/owncast/static"
- "github.com/owncast/owncast/utils"
- log "github.com/sirupsen/logrus"
- )
- func appendOfflineToVariantPlaylist(index int, playlistFilePath string) {
- existingPlaylistContents, err := os.ReadFile(playlistFilePath) // nolint: gosec
- if err != nil {
- log.Debugln("unable to read existing playlist file", err)
- return
- }
- tmpFileName := fmt.Sprintf("tmp-stream-%d.m3u8", index)
- atomicWriteTmpPlaylistFile, err := os.CreateTemp(config.TempDir, tmpFileName)
- if err != nil {
- log.Errorln("error creating tmp playlist file to write to", playlistFilePath, err)
- return
- }
- // Write the existing playlist contents
- if _, err := atomicWriteTmpPlaylistFile.Write(existingPlaylistContents); err != nil {
- log.Debugln("error writing existing playlist contents to tmp playlist file", err)
- return
- }
- // Manually append the offline clip to the end of the media playlist.
- _, _ = atomicWriteTmpPlaylistFile.WriteString("#EXT-X-DISCONTINUITY\n")
- // If "offline" content gets changed then change the duration below
- _, _ = atomicWriteTmpPlaylistFile.WriteString("#EXTINF:8.000000,\n")
- _, _ = atomicWriteTmpPlaylistFile.WriteString("offline.ts\n")
- _, _ = atomicWriteTmpPlaylistFile.WriteString("#EXT-X-ENDLIST\n")
- if err := atomicWriteTmpPlaylistFile.Close(); err != nil {
- log.Errorln(err)
- }
- if err := utils.Move(atomicWriteTmpPlaylistFile.Name(), playlistFilePath); err != nil {
- log.Errorln("error moving temp playlist to overwrite existing one", err)
- }
- }
- func makeVariantIndexOffline(index int, offlineFilePath string, offlineFilename string) {
- playlistFilePath := fmt.Sprintf(filepath.Join(config.HLSStoragePath, "%d/stream.m3u8"), index)
- segmentFilePath := fmt.Sprintf(filepath.Join(config.HLSStoragePath, "%d/%s"), index, offlineFilename)
- if err := utils.Copy(offlineFilePath, segmentFilePath); err != nil {
- log.Warnln(err)
- }
- if _, err := _storage.Save(segmentFilePath, 0); err != nil {
- log.Warnln(err)
- }
- if utils.DoesFileExists(playlistFilePath) {
- appendOfflineToVariantPlaylist(index, playlistFilePath)
- } else {
- createEmptyOfflinePlaylist(playlistFilePath, offlineFilename)
- }
- if _, err := _storage.Save(playlistFilePath, 0); err != nil {
- log.Warnln(err)
- }
- }
- func createEmptyOfflinePlaylist(playlistFilePath string, offlineFilename string) {
- p, err := m3u8.NewMediaPlaylist(1, 1)
- if err != nil {
- log.Errorln(err)
- }
- // If "offline" content gets changed then change the duration below
- if err := p.Append(offlineFilename, 8.0, ""); err != nil {
- log.Errorln(err)
- }
- p.Close()
- f, err := os.Create(playlistFilePath) //nolint:gosec
- if err != nil {
- log.Errorln(err)
- }
- defer f.Close()
- if _, err := f.Write(p.Encode().Bytes()); err != nil {
- log.Errorln(err)
- }
- }
- func saveOfflineClipToDisk(offlineFilename string) (string, error) {
- offlineFileData := static.GetOfflineSegment()
- offlineTmpFile, err := os.CreateTemp(config.TempDir, offlineFilename)
- if err != nil {
- log.Errorln("unable to create temp file for offline video segment", err)
- }
- if _, err = offlineTmpFile.Write(offlineFileData); err != nil {
- return "", fmt.Errorf("unable to write offline segment to disk: %s", err)
- }
- offlineFilePath := offlineTmpFile.Name()
- return offlineFilePath, nil
- }
|