Skip to content
This repository has been archived by the owner on Feb 28, 2018. It is now read-only.

Commit

Permalink
Don't cache to file
Browse files Browse the repository at this point in the history
  • Loading branch information
Niels Hofmans committed Jan 12, 2018
1 parent 41a19fd commit 55568c7
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 69 deletions.
2 changes: 0 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
func main() {
listenHost := flag.String("host", "localhost", "What address to listen on.")
listenPort := flag.Int("port", 8080, "What port to listen on.")
tempPath := flag.String("temp", "/tmp/m3u", "What location to store the downloaded M3U file.")
maxStreams := flag.Int("streams", 1, "How many streams can be played simultaneously.")
flag.Parse()

Expand All @@ -23,7 +22,6 @@ func main() {

muxy.SetListenHost(*listenHost)
muxy.SetListenPort(*listenPort)
muxy.SetTempM3UPath(*tempPath)
muxy.SetMaxStreams(*maxStreams)
muxy.SetM3UFile(m3uPath)

Expand Down
2 changes: 0 additions & 2 deletions muxy/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ var m3ufile = "playlist.m3u"
var listenPort = 8080
var listenHost = "localhost"
var tunerCount = 1
var tempM3UFile = "/tmp/muxy/m3u"
var tempTSDirectory = "/tmp/muxy/ts"

var listenUrl = "http://" + listenHost + ":" + strconv.Itoa(listenPort)
var deviceInfo = map[string]string{
Expand Down
6 changes: 0 additions & 6 deletions muxy/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,6 @@ func SetListenPort(port int) {
listenPort = port
}

func SetTempM3UPath(path string) {
tempM3UFile = path
}

func RunListener() {
router := mux.NewRouter()

Expand All @@ -134,8 +130,6 @@ func RunListener() {

router.HandleFunc("/stream/{link:.*}", streamChannel).Methods("GET")

removeTempFile()

err := http.ListenAndServe(
listenHost + ":" + strconv.Itoa(listenPort),
logRequest(router),
Expand Down
86 changes: 39 additions & 47 deletions muxy/m3uparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import (
"github.com/grafov/m3u8"
"os"
"net/http"
"io"
"errors"
log "github.com/golang/glog"
"strings"
"strconv"
"encoding/base64"
"io/ioutil"
)

type Channel struct {
Expand All @@ -29,53 +29,40 @@ func isValidUrl(toTest string) bool {
return strings.Contains(strings.ToLower(toTest), "http")
}

func downloadFile(url string, result string) (string, error) {
out, err := os.Create(result)
func downloadFile(url string) (string, error) {

client := &http.Client{}

req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", errors.New("Could not create temp M3U file: " + err.Error())
return "", errors.New("Could not request segment: " + err.Error())
}

defer out.Close()

resp, err := http.Get(url)
req.Header.Set("User-Agent", "vlc 1.1.0-git-20100330-0003")
resp, err := client.Do(req)

if err != nil || (resp != nil && (resp.StatusCode >= 400)){
if err != nil {
return "", errors.New("HTTP request failed: " + err.Error())
}

defer resp.Body.Close()

_, err = io.Copy(out, resp.Body)

if err != nil {
return "", errors.New("Could not copy to temp path: " + err.Error())
if resp.StatusCode != http.StatusOK {
return "", errors.New("M3U fetch returned code: " + strconv.Itoa(resp.StatusCode))
}

log.Info("Downloaded to " + result)
return result, nil
}

func removeTempFile() {
os.Remove(tempM3UFile)
}

/*
func isFileFresh(path string) bool {
info, err := os.Stat(path)
bodyBytes, err := ioutil.ReadAll(resp.Body)

if err != nil {
return false
return "", errors.New("Could not read file contents: " + err.Error())
}

expiryDate := time.Now().Add(time.Duration(cacheTimeMinutes * -1) * time.Minute)
return true == info.ModTime().After(expiryDate)
return string(bodyBytes), nil
}
*/

func getChannelPlaylist(m3uPath string) ([]Channel, error) {

mediaPlayList, err := parseM3UFile(m3uPath, tempM3UFile)
mediaPlayList, err := parseM3UFile(m3uPath)
if err != nil {
return nil, errors.New(err.Error())
}
Expand All @@ -97,43 +84,48 @@ func getChannelPlaylist(m3uPath string) ([]Channel, error) {
return channels, nil
}

func parseM3UFile(path string, temp string) (MediaPlaylistWrapper, error) {
func parseM3UFile(path string) (MediaPlaylistWrapper, error) {

var mediaWrappper MediaPlaylistWrapper
var m3uContent string

if isValidUrl(path) == true {
log.Info("Downloading " + path)

downloadedPath, err := downloadFile(path, temp)

str, err := downloadFile(path)
if err != nil {
return mediaWrappper, err
}

path = downloadedPath
}

log.Info("Using M3U file: " + path)
m3uContent = str
} else {
log.Info("Using M3U file: " + path)

readFile, err := os.Open(path)
readFile, err := os.Open(path)
if err != nil {
return mediaWrappper, errors.New("Could not open file " + path)
}

if err != nil {
return mediaWrappper, errors.New("Could not open file " + path)
}
defer readFile.Close()

defer readFile.Close()
fileStat, err := readFile.Stat()
if err != nil {
return mediaWrappper, errors.New("Could not examine file " + path)
}

fileStat, err := readFile.Stat()
if fileStat.Size() == 0 {
return mediaWrappper, errors.New("M3U file is empty")
}

if err != nil {
return mediaWrappper, errors.New("Could not examine file " + path)
}
bytesRead, err := ioutil.ReadAll(readFile)
if err != nil {
return mediaWrappper, errors.New("Could not read M3U: " + err.Error())
}

if fileStat.Size() == 0 {
return mediaWrappper, errors.New("M3U file is empty")
m3uContent = string(bytesRead)
}

playList, listType, err := m3u8.DecodeFrom(readFile, false)
playList, listType, err := m3u8.DecodeFrom(strings.NewReader(m3uContent), false)

if err != nil {
return mediaWrappper, errors.New("Could not parse M3U: " + err.Error())
Expand Down
21 changes: 9 additions & 12 deletions muxy/streamer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ func startChannelStream(writer http.ResponseWriter, channelPlaylist string) {
break refetch
}

req.Header.Set("User-Agent", "VLC")
req.Header.Set("User-Agent", "vlc 1.1.0-git-20100330-0003")

response, err := client.Do(req)

defer response.Body.Close()

if err != nil || (response != nil && response.StatusCode != 200) {
if err != nil || (response != nil && response.StatusCode != http.StatusOK) {

if response == nil {
log.Error("Could not fetch segment: " + err.Error())
Expand All @@ -80,12 +80,15 @@ func startChannelStream(writer http.ResponseWriter, channelPlaylist string) {
// rate limited
log.Warning("Rate limited, waiting for " + response.Header.Get("Retry-After") + " seconds")
secWait, _ := strconv.Atoi(response.Header.Get("Retry-After"))

writer.WriteHeader(503)

time.Sleep(time.Second * time.Duration(secWait))
break refetch
}
}

if response.StatusCode != 200 {
if response.StatusCode != http.StatusOK {
log.Warning("Status code is " + strconv.Itoa(response.StatusCode))
continue
}
Expand All @@ -103,20 +106,14 @@ func startChannelStream(writer http.ResponseWriter, channelPlaylist string) {
waitForNextSegment()
}
}

}

func FetchStreamSegments(url string, streamID string) ([]Channel, error) {

tempStreamPath := tempTSDirectory + "/" + streamID
log.Info("Stream temp dir will be " + tempStreamPath)

if nil != prepareCacheDir(tempStreamPath) {
return nil, errors.New("Could not create stream cache dir: " + tempStreamPath)
}

tempStreamFilename := tempStreamPath + "/" + streamID
log.Info("Fetching segments for stream " + streamID)

mediaPlayList, err := parseM3UFile(url, tempStreamFilename)
mediaPlayList, err := parseM3UFile(url)
if err != nil {
return nil, errors.New("Could not get channel playlist: " + err.Error())
}
Expand Down

0 comments on commit 55568c7

Please sign in to comment.