Merge branch 'pr/134' into beta
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
#### 2.1.1.0116-beta
|
||||
If no user agent is specified, the default FFmpeg or VLC user agent is used.
|
||||
|
||||
#### 2.1.1.0115-beta
|
||||
```diff
|
||||
+ GZIP compression for xteve.xml file. (http://xteve.ip:34400/xmltv/xteve.xml.gz)
|
||||
- Removed protocol setting for reverse proxy. HTTPS can also be configured in the proxy, where it makes more sense.
|
||||
```
|
||||
|
||||
#### 2.1.0.0106-beta
|
||||
```diff
|
||||
+ User-Agent is now also used by VLC and FFmpeg.
|
||||
|
||||
@@ -20,7 +20,7 @@ menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.p
|
||||
var settingsCategory = new Array();
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,udpxy,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"));
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"));
|
||||
function showPopUpElement(elm) {
|
||||
|
||||
@@ -305,6 +305,17 @@ var SettingsCategory = /** @class */ (function () {
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
case "udpxy":
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.udpxy.title}}" + ":";
|
||||
var tdRight = document.createElement("TD");
|
||||
var input = content.createInput("text", "udpxy", data);
|
||||
input.setAttribute("placeholder", "{{.settings.udpxy.placeholder}}");
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'");
|
||||
tdRight.appendChild(input);
|
||||
setting.appendChild(tdLeft);
|
||||
setting.appendChild(tdRight);
|
||||
break;
|
||||
}
|
||||
return setting;
|
||||
};
|
||||
@@ -386,6 +397,9 @@ var SettingsCategory = /** @class */ (function () {
|
||||
case "xepg.replace.missing.images":
|
||||
text = "{{.settings.replaceEmptyImages.description}}";
|
||||
break;
|
||||
case "udpxy":
|
||||
text = "{{.settings.udpxy.description}}";
|
||||
break;
|
||||
default:
|
||||
text = "";
|
||||
break;
|
||||
|
||||
@@ -183,52 +183,52 @@
|
||||
"active": {
|
||||
"title": "Active",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"channelName": {
|
||||
"title": "Channel Name",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"description": {
|
||||
"title": "Channel Description",
|
||||
"placeholder": "Used by the Dummy as an XML description",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"updateChannelName": {
|
||||
"title": "Update Channel Name",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"channelLogo": {
|
||||
"title": "Logo URL",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"updateChannelLogo": {
|
||||
"title": "Update Channel Logo",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"epgCategory": {
|
||||
"title": "EPG Category",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"m3uGroupTitle": {
|
||||
"title": "Group Title (xteve.m3u)",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"xmltvFile": {
|
||||
"title": "XMLTV File",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
},
|
||||
"xmltvChannel": {
|
||||
"title": "XMLTV Channel",
|
||||
"placeholder": "",
|
||||
"description": ""
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
@@ -332,6 +332,11 @@
|
||||
"info_vlc": "VLC connects to the streaming server"
|
||||
|
||||
},
|
||||
"udpxy": {
|
||||
"title": "UDPxy address",
|
||||
"description": "The address of your UDPxy server. If set, and the channel URLs in the m3u is multicast, xTeVe will rewrite it so that it is accessed via the UDPxy service.",
|
||||
"placeholder": "host:port"
|
||||
},
|
||||
"ffmpegPath": {
|
||||
"title": "FFmpeg Binary Path",
|
||||
"description": "Path to FFmpeg binary.",
|
||||
|
||||
@@ -15,7 +15,7 @@ var System SystemStruct
|
||||
var WebScreenLog WebScreenLogStruct
|
||||
|
||||
// Settings : Inhalt der settings.json
|
||||
var Settings SettingsStrcut
|
||||
var Settings SettingsStruct
|
||||
|
||||
// Data : Alle Daten werden hier abgelegt. (Lineup, XMLTV)
|
||||
var Data DataStruct
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
// Einstellungen ändern (WebUI)
|
||||
func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err error) {
|
||||
func updateServerSettings(request RequestStruct) (settings SettingsStruct, err error) {
|
||||
|
||||
var oldSettings = jsonToMap(mapToJSON(Settings))
|
||||
var newSettings = jsonToMap(mapToJSON(request.Settings))
|
||||
@@ -408,7 +408,7 @@ func deleteLocalProviderFiles(dataID, fileType string) {
|
||||
}
|
||||
|
||||
// Filtereinstellungen speichern (WebUI)
|
||||
func saveFilter(request RequestStruct) (settings SettingsStrcut, err error) {
|
||||
func saveFilter(request RequestStruct) (settings SettingsStruct, err error) {
|
||||
|
||||
var filterMap = make(map[int64]interface{})
|
||||
var newData = make(map[int64]interface{})
|
||||
|
||||
@@ -86,6 +86,7 @@ func ShowSystemInfo() {
|
||||
|
||||
fmt.Println("Settings [Streaming]")
|
||||
fmt.Println(fmt.Sprintf("Buffer: %s", Settings.Buffer))
|
||||
fmt.Println(fmt.Sprintf("UDPxy: %s", Settings.UDPxy))
|
||||
fmt.Println(fmt.Sprintf("Buffer Size: %d KB", Settings.BufferSize))
|
||||
fmt.Println(fmt.Sprintf("Timeout: %d ms", int(Settings.BufferTimeout)))
|
||||
fmt.Println(fmt.Sprintf("User Agent: %s", Settings.UserAgent))
|
||||
|
||||
@@ -99,6 +99,7 @@ type SystemStruct struct {
|
||||
}
|
||||
|
||||
URLBase string
|
||||
UDPxy string
|
||||
Version string
|
||||
WEB struct {
|
||||
Menu []string
|
||||
@@ -246,8 +247,8 @@ type Notification struct {
|
||||
Type string `json:"type,required"`
|
||||
}
|
||||
|
||||
// SettingsStrcut : Inhalt der settings.json
|
||||
type SettingsStrcut struct {
|
||||
// SettingsStruct : Inhalt der settings.json
|
||||
type SettingsStruct struct {
|
||||
API bool `json:"api"`
|
||||
AuthenticationAPI bool `json:"authentication.api"`
|
||||
AuthenticationM3U bool `json:"authentication.m3u"`
|
||||
@@ -290,6 +291,7 @@ type SettingsStrcut struct {
|
||||
UpdateURL string `json:"update.url,omitempty"`
|
||||
UserAgent string `json:"user.agent"`
|
||||
UUID string `json:"uuid"`
|
||||
UDPxy string `json:"udpxy"`
|
||||
Version string `json:"version"`
|
||||
XepgReplaceMissingImages bool `json:"xepg.replace.missing.images"`
|
||||
XteveAutoUpdate bool `json:"xteveAutoUpdate"`
|
||||
|
||||
@@ -37,6 +37,7 @@ type RequestStruct struct {
|
||||
FilesUpdate *bool `json:"files.update,omitempty"`
|
||||
TempPath *string `json:"temp.path,omitempty"`
|
||||
Tuner *int `json:"tuner,omitempty"`
|
||||
UDPxy *string `json:"udpxy,omitempty"`
|
||||
Update *[]string `json:"update,omitempty"`
|
||||
UserAgent *string `json:"user.agent,omitempty"`
|
||||
XepgReplaceMissingImages *bool `json:"xepg.replace.missing.images,omitempty"`
|
||||
@@ -109,7 +110,7 @@ type ResponseStruct struct {
|
||||
OpenLink string `json:"openLink,omitempty"`
|
||||
OpenMenu string `json:"openMenu,omitempty"`
|
||||
Reload bool `json:"reload,omitempty"`
|
||||
Settings SettingsStrcut `json:"settings,required"`
|
||||
Settings SettingsStruct `json:"settings,required"`
|
||||
Status bool `json:"status,required"`
|
||||
Token string `json:"token,omitempty"`
|
||||
Users map[string]interface{} `json:"users,omitempty"`
|
||||
|
||||
@@ -90,7 +90,7 @@ func createSystemFiles() (err error) {
|
||||
}
|
||||
|
||||
// Einstellungen laden und default Werte setzen (xTeVe)
|
||||
func loadSettings() (settings SettingsStrcut, err error) {
|
||||
func loadSettings() (settings SettingsStruct, err error) {
|
||||
|
||||
settingsMap, err := loadJSONFileToMap(System.File.Settings)
|
||||
if err != nil {
|
||||
@@ -135,6 +135,7 @@ func loadSettings() (settings SettingsStrcut, err error) {
|
||||
defaults["update"] = []string{"0000"}
|
||||
defaults["user.agent"] = System.Name
|
||||
defaults["uuid"] = createUUID()
|
||||
defaults["udpxy"] = ""
|
||||
defaults["version"] = System.DBVersion
|
||||
defaults["xteveAutoUpdate"] = true
|
||||
defaults["temp.path"] = System.Folder.Temp
|
||||
@@ -186,7 +187,7 @@ func loadSettings() (settings SettingsStrcut, err error) {
|
||||
}
|
||||
|
||||
// Einstellungen speichern (xTeVe)
|
||||
func saveSettings(settings SettingsStrcut) (err error) {
|
||||
func saveSettings(settings SettingsStruct) (err error) {
|
||||
|
||||
if settings.BackupKeep == 0 {
|
||||
settings.BackupKeep = 10
|
||||
|
||||
65
src/webUI.go
65
src/webUI.go
File diff suppressed because one or more lines are too long
@@ -30,6 +30,7 @@ func StartWebserver() (err error) {
|
||||
http.HandleFunc("/api/", API)
|
||||
http.HandleFunc("/images/", Images)
|
||||
http.HandleFunc("/data_images/", DataImages)
|
||||
|
||||
//http.HandleFunc("/auto/", Auto)
|
||||
|
||||
showInfo("DVR IP:" + System.IPAddress + ":" + Settings.Port)
|
||||
@@ -129,6 +130,12 @@ func Stream(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// If an UDPxy host is set, and the stream URL is multicast (i.e. starts with 'udp://@'),
|
||||
// then streamInfo.URL needs to be rewritten to point to UDPxy.
|
||||
if Settings.UDPxy != "" && strings.HasPrefix(streamInfo.URL, "udp://@") {
|
||||
streamInfo.URL = fmt.Sprintf("http://%s/udp/%s/", Settings.UDPxy, strings.TrimPrefix(streamInfo.URL, "udp://@"))
|
||||
}
|
||||
|
||||
switch Settings.Buffer {
|
||||
|
||||
case "-":
|
||||
|
||||
@@ -22,7 +22,7 @@ menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.p
|
||||
// Kategorien für die Einstellungen
|
||||
var settingsCategory = new Array()
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api"));settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.streaming}}", "buffer,udpxy,buffer.size.kb,buffer.timeout,user.agent,ffmpeg.path,ffmpeg.options,vlc.path,vlc.options"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.backup}}", "backup.path,backup.keep"))
|
||||
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.authentication}}", "authentication.web,authentication.pms,authentication.m3u,authentication.xml,authentication.api"))
|
||||
|
||||
@@ -408,7 +408,7 @@ function changeChannelNumber(element) {
|
||||
})
|
||||
|
||||
for (var i = 0; i < channelNumbers.length; i++) {
|
||||
|
||||
|
||||
if (channelNumbers.indexOf(newNumber) == -1) {
|
||||
break
|
||||
}
|
||||
@@ -422,7 +422,7 @@ function changeChannelNumber(element) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
data[dbID]["x-channelID"] = newNumber.toString()
|
||||
element.value = newNumber
|
||||
|
||||
@@ -461,7 +461,7 @@ function toggleChannelStatus(id:string) {
|
||||
var checkbox = (document.getElementById("active") as HTMLInputElement)
|
||||
status = (checkbox).checked
|
||||
}
|
||||
|
||||
|
||||
|
||||
var ids:string[] = getAllSelectedChannels()
|
||||
if (ids.length == 0) {
|
||||
@@ -482,9 +482,9 @@ function toggleChannelStatus(id:string) {
|
||||
alert(channel["x-name"] + ": Missing XMLTV file / channel")
|
||||
checkbox.checked = false
|
||||
}
|
||||
|
||||
|
||||
channel["x-active"] = false
|
||||
|
||||
|
||||
}
|
||||
|
||||
break
|
||||
@@ -621,9 +621,9 @@ function checkUndo(key:string) {
|
||||
UNDO[key] = JSON.parse(JSON.stringify(SERVER["xepg"][key]));
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -646,9 +646,9 @@ function sortSelect(elem) {
|
||||
|
||||
elem.options[i] = tmpAry[i];
|
||||
if(elem.options[i].value == selectedValue) newSelectedIndex = i;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
elem.selectedIndex = newSelectedIndex; // Set new selected index after sorting
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -372,19 +372,34 @@ class SettingsCategory {
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
case "udpxy":
|
||||
|
||||
var tdLeft = document.createElement("TD");
|
||||
tdLeft.innerHTML = "{{.settings.udpxy.title}}" + ":"
|
||||
|
||||
var tdRight = document.createElement("TD")
|
||||
var input = content.createInput("text", "udpxy", data)
|
||||
input.setAttribute("placeholder", "{{.settings.udpxy.placeholder}}")
|
||||
input.setAttribute("onchange", "javascript: this.className = 'changed'")
|
||||
tdRight.appendChild(input)
|
||||
|
||||
setting.appendChild(tdLeft)
|
||||
setting.appendChild(tdRight)
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
return setting
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
createDescription(settingsKey:string):any {
|
||||
|
||||
var description = document.createElement("TR")
|
||||
var text:string
|
||||
switch (settingsKey) {
|
||||
|
||||
|
||||
case "authentication.web":
|
||||
text = "{{.settings.authenticationWEB.description}}"
|
||||
break
|
||||
@@ -483,10 +498,14 @@ class SettingsCategory {
|
||||
text = "{{.settings.replaceEmptyImages.description}}"
|
||||
break
|
||||
|
||||
case "udpxy":
|
||||
text = "{{.settings.udpxy.description}}"
|
||||
break
|
||||
|
||||
default:
|
||||
text = ""
|
||||
break
|
||||
|
||||
|
||||
}
|
||||
|
||||
var tdLeft = document.createElement("TD")
|
||||
@@ -499,7 +518,7 @@ class SettingsCategory {
|
||||
|
||||
description.appendChild(tdLeft)
|
||||
description.appendChild(tdRight)
|
||||
|
||||
|
||||
return description
|
||||
|
||||
}
|
||||
@@ -519,12 +538,12 @@ class SettingsCategoryItem extends SettingsCategory {
|
||||
createCategory():void {
|
||||
var headline = this.createCategoryHeadline(this.headline)
|
||||
var settingsKeys = this.settingsKeys
|
||||
|
||||
|
||||
var doc = document.getElementById(this.DocumentID)
|
||||
doc.appendChild(headline)
|
||||
|
||||
// Tabelle für die Kategorie erstellen
|
||||
|
||||
|
||||
var table = document.createElement("TABLE")
|
||||
|
||||
var keys = settingsKeys.split(",")
|
||||
@@ -565,7 +584,7 @@ function showSettings() {
|
||||
for (let i = 0; i < settingsCategory.length; i++) {
|
||||
settingsCategory[i].createCategory()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function saveSettings() {
|
||||
@@ -627,7 +646,7 @@ function saveSettings() {
|
||||
break
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
var data = new Object()
|
||||
|
||||
9
xteve.go
9
xteve.go
@@ -47,9 +47,6 @@ const DBVersion = "2.1.0"
|
||||
// APIVersion : API Version
|
||||
const APIVersion = "1.1.0"
|
||||
|
||||
// Dev : Aktiviert den Entwicklungsmodus. Für den Webserver werden dann die lokalen Dateien verwendet.
|
||||
const Dev = false
|
||||
|
||||
var homeDirectory = fmt.Sprintf("%s%s.%s%s", src.GetUserHomeDirectory(), string(os.PathSeparator), strings.ToLower(Name), string(os.PathSeparator))
|
||||
var samplePath = fmt.Sprintf("%spath%sto%sxteve%s", string(os.PathSeparator), string(os.PathSeparator), string(os.PathSeparator), string(os.PathSeparator))
|
||||
var sampleRestore = fmt.Sprintf("%spath%sto%sfile%s", string(os.PathSeparator), string(os.PathSeparator), string(os.PathSeparator), string(os.PathSeparator))
|
||||
@@ -63,6 +60,9 @@ var debug = flag.Int("debug", 0, ": Debug level [0 - 3] (default: 0)")
|
||||
var info = flag.Bool("info", false, ": Show system info")
|
||||
var h = flag.Bool("h", false, ": Show help")
|
||||
|
||||
// Aktiviert den Entwicklungsmodus. Für den Webserver werden dann die lokalen Dateien verwendet.
|
||||
var dev = flag.Bool("dev", false, ": Activates the developer mode, the source code must be available. The local files for the web interface are used.")
|
||||
|
||||
func main() {
|
||||
|
||||
// Build-Nummer von der Versionsnummer trennen
|
||||
@@ -73,7 +73,6 @@ func main() {
|
||||
system.Branch = GitHub.Branch
|
||||
system.Build = build[len(build)-1:][0]
|
||||
system.DBVersion = DBVersion
|
||||
system.Dev = Dev
|
||||
system.GitHub = GitHub
|
||||
system.Name = Name
|
||||
system.Version = strings.Join(build[0:len(build)-1], ".")
|
||||
@@ -122,6 +121,8 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
system.Dev = *dev
|
||||
|
||||
// Systeminformationen anzeigen
|
||||
if *info {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user