17 Commits

Author SHA1 Message Date
marmei
66c01dd1fb Missing placeholder 2019-12-13 21:05:14 +01:00
marmei
03e1abbe90 v2.1.1.0110 2019-12-13 20:31:23 +01:00
marmei
469581e280 Add mapping desc. function 2019-12-13 19:01:18 +01:00
marmei
019c98996a Update changelog-beta.md 2019-12-08 2019-12-08 17:49:50 +01:00
marmei
36db927794 v2.1.0.0106 2019-12-08 17:47:54 +01:00
marmei
f0a49788cc User-Agent for FFmpeg and VLC 2019-12-08 17:33:46 +01:00
marmei
72767d7dbd Update changelog-beta.md 2019-12-06 2019-12-06 21:00:44 +01:00
marmei
8eecbf2b78 Update changelog-beta.md 2019-12-06 2019-12-06 20:57:26 +01:00
marmei
1a1e37fe15 v2.1.0.0105: Settings for URI scheme 2019-12-06 20:48:59 +01:00
marmei
08f6fb60e3 Fix log entry, wrong buffer value 2019-11-15 10:09:19 +01:00
marmei
eded490ac7 Update changelog-beta.md 2019-11-06 2019-11-06 18:16:14 +01:00
marmei
ed770b9dbc Merge remote-tracking branch 'origin/master' 2019-11-06 18:11:21 +01:00
marmei
6129b4911a Merge pull request #53 from taeram/patch-1
Small spelling / grammar fixes.
2019-11-05 20:29:12 +01:00
Jesse Patching
477c5f30c1 Small spelling / grammar fixes. 2019-11-04 20:28:45 -07:00
marmei
65ddc6f301 v2.1.2.0101-beta 2019-11-04 18:28:41 +01:00
marmei
3ef95c1950 RV Proxy 2019-11-04 18:23:20 +01:00
marmei
3a3798cd2d WiteHeader 2019-10-23 19:02:54 +02:00
21 changed files with 250 additions and 60 deletions

View File

@@ -31,7 +31,7 @@ Documentation for setup and configuration is [here](https://github.com/xteve-pro
* Merge external M3U files * Merge external M3U files
* Merge external XMLTV files * Merge external XMLTV files
* Automatic M3U and XMLTV update * Automatic M3U and XMLTV update
* M3U und XMLTV export * M3U and XMLTV export
#### Channel management #### Channel management
* Filtering streams * Filtering streams
@@ -84,7 +84,7 @@ Including:
--- ---
### xTeVe Beta branch ### xTeVe Beta branch
New features and bug fixes are only available in beta brunch. Only after successful testing, they are merged into the master branch. New features and bug fixes are only available in beta branch. Only after successful testing are they are merged into the master branch.
**It is not recommended to use the beta version in a production system.** **It is not recommended to use the beta version in a production system.**

View File

@@ -1,3 +1,20 @@
#### 2.1.0.0106-beta
```diff
+ User-Agent is now also used by VLC and FFmpeg.
```
#### 2.1.0.0105-beta
```diff
+ Fixed wrong buffer value in log
+ New setting: URL protocol for M3U and XML file
+ Add xml tag premiere to xteve.xml
```
#### 2.1.0.0101-beta
```diff
+ Reverse proxy fix
```
#### 2.0.3.0042-beta #### 2.0.3.0042-beta
**Version 2.0.3.0042 changes the settings.json.** **Version 2.0.3.0042 changes the settings.json.**
Settings from the current beta can not be used for the current master version 2.0.3 Settings from the current beta can not be used for the current master version 2.0.3

View File

@@ -18,7 +18,7 @@ menuItems.push(new MainMenuItem("log", "{{.mainMenu.item.log}}", "log.png", "{{.
menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.png", "{{.mainMenu.headline.logout}}")); menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.png", "{{.mainMenu.headline.logout}}"));
// Kategorien für die Einstellungen // Kategorien für die Einstellungen
var settingsCategory = new Array(); var settingsCategory = new Array();
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api")); settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api,scheme.m3u,scheme.xml"));
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images")); 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,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.backup}}", "backup.path,backup.keep"));

View File

@@ -1253,6 +1253,12 @@ function openPopUp(dataType, element) {
} }
content.appendRow("{{.mapping.channelName.title}}", input); content.appendRow("{{.mapping.channelName.title}}", input);
content.description(data["name"]); content.description(data["name"]);
// Beschreibung
var dbKey = "x-description";
var input = content.createInput("text", dbKey, data[dbKey]);
input.setAttribute("placeholder", "{{.mapping.description.placeholder}}");
input.setAttribute("onchange", "javascript: this.className = 'changed'");
content.appendRow("{{.mapping.description.title}}", input);
// Aktualisierung des Kanalnamens // Aktualisierung des Kanalnamens
if (data.hasOwnProperty("_uuid.key")) { if (data.hasOwnProperty("_uuid.key")) {
if (data["_uuid.key"] != "") { if (data["_uuid.key"] != "") {

View File

@@ -305,6 +305,30 @@ var SettingsCategory = /** @class */ (function () {
setting.appendChild(tdLeft); setting.appendChild(tdLeft);
setting.appendChild(tdRight); setting.appendChild(tdRight);
break; break;
case "scheme.m3u":
var tdLeft = document.createElement("TD");
tdLeft.innerHTML = "{{.settings.schemeM3U.title}}" + ":";
var tdRight = document.createElement("TD");
var text = ["HTTP", "HTTPS"];
var values = ["HTTP", "HTTPS"];
var select = content.createSelect(text, values, data, settingsKey);
select.setAttribute("onchange", "javascript: this.className = 'changed'");
tdRight.appendChild(select);
setting.appendChild(tdLeft);
setting.appendChild(tdRight);
break;
case "scheme.xml":
var tdLeft = document.createElement("TD");
tdLeft.innerHTML = "{{.settings.schemeXML.title}}" + ":";
var tdRight = document.createElement("TD");
var text = ["HTTP", "HTTPS"];
var values = ["HTTP", "HTTPS"];
var select = content.createSelect(text, values, data, settingsKey);
select.setAttribute("onchange", "javascript: this.className = 'changed'");
tdRight.appendChild(select);
setting.appendChild(tdLeft);
setting.appendChild(tdRight);
break;
} }
return setting; return setting;
}; };
@@ -386,6 +410,12 @@ var SettingsCategory = /** @class */ (function () {
case "xepg.replace.missing.images": case "xepg.replace.missing.images":
text = "{{.settings.replaceEmptyImages.description}}"; text = "{{.settings.replaceEmptyImages.description}}";
break; break;
case "scheme.m3u":
text = "{{.settings.schemeM3U.description}}";
break;
case "scheme.xml":
text = "{{.settings.schemeXML.description}}";
break;
default: default:
text = ""; text = "";
break; break;

View File

@@ -190,6 +190,11 @@
"placeholder": "", "placeholder": "",
"description": "" "description": ""
}, },
"description": {
"title": "Channel Description",
"placeholder": "Used by the Dummy as an XML description",
"description": ""
},
"updateChannelName": { "updateChannelName": {
"title": "Update Channel Name", "title": "Update Channel Name",
"placeholder": "", "placeholder": "",
@@ -302,6 +307,14 @@
"title": "Number of Tuners", "title": "Number of Tuners",
"description": "Number of parallel connections that can be established to the provider.<br>Available for: Plex, Emby (HDHR), M3U (with active buffer).<br>After a change, xTeVe must be delete in the Plex / Emby DVR settings and set up again." "description": "Number of parallel connections that can be established to the provider.<br>Available for: Plex, Emby (HDHR), M3U (with active buffer).<br>After a change, xTeVe must be delete in the Plex / Emby DVR settings and set up again."
}, },
"schemeM3U":{
"title": "URL protocol for xteve.m3u",
"description": "Determines which URL protocol is used for the xTeVe streaming URLs. If you using a reverse proxy over HTTPS, set this to HTTPS."
},
"schemeXML":{
"title": "URL protocol for xteve.xml",
"description": "Determines which URL protocol is used for the xTeVe image URLs. If you using a reverse proxy over HTTPS, set this to HTTPS."
},
"filesUpdate": { "filesUpdate": {
"title": "Updates all files at startup", "title": "Updates all files at startup",
"description": "Updates all playlists, tuner and XMLTV files at startup." "description": "Updates all playlists, tuner and XMLTV files at startup."
@@ -358,7 +371,7 @@
}, },
"userAgent": { "userAgent": {
"title": "User Agent", "title": "User Agent",
"description": "User Agent for HTTP requests. Only used if xTeVe is selected as the buffer.", "description": "User Agent for HTTP requests. For every HTTP connection, this value is used for the user agent. Should only be changed if xTeVe is blocked.",
"placeholder": "xTeVe" "placeholder": "xTeVe"
}, },
"backupPath": { "backupPath": {

View File

@@ -228,7 +228,7 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
} }
w.WriteHeader(200) //w.WriteHeader(200)
for { // Loop 1: Warten bis das erste Segment durch den Buffer heruntergeladen wurde for { // Loop 1: Warten bis das erste Segment durch den Buffer heruntergeladen wurde
@@ -261,7 +261,9 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
var oldSegments []string var oldSegments []string
for { // Loop 2: Temporäre Datein sind vorhanden, Daten können zum Client gesendet werden for { // Loop 2: Temporäre Datein sind vorhanden, Daten können zum Client gesendet werden
// HTTP Clientverbindung überwachen // HTTP Clientverbindung überwachen
cn, ok := w.(http.CloseNotifier) cn, ok := w.(http.CloseNotifier)
if ok { if ok {
@@ -330,10 +332,10 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
if streaming == false { if streaming == false {
contentType := http.DetectContentType(buffer) contentType := http.DetectContentType(buffer) + "; name=stream.ts"
_ = contentType //_ = contentType
//w.Header().Set("Content-type", "video/mpeg") //w.Header().Set("Content-type", "video/mpeg")
w.Header().Set("Content-type", contentType) w.Header().Add("Content-type", contentType)
w.Header().Set("Content-Length", "0") w.Header().Set("Content-Length", "0")
w.Header().Set("Connection", "close") w.Header().Set("Connection", "close")
@@ -346,6 +348,7 @@ func bufferingStream(playlistID, streamingURL, channelName string, w http.Respon
w.Header().Set("transferMode.dlna.org", "Streaming") w.Header().Set("transferMode.dlna.org", "Streaming")
*/ */
w.WriteHeader(200)
_, err := w.Write(buffer) _, err := w.Write(buffer)
if err != nil { if err != nil {
@@ -449,6 +452,9 @@ func getTmpFiles(stream *ThisStream) (tmpFiles []string) {
func killClientConnection(streamID int, playlistID string, force bool) { func killClientConnection(streamID int, playlistID string, force bool) {
Lock.Lock()
defer Lock.Unlock()
if p, ok := BufferInformation.Load(playlistID); ok { if p, ok := BufferInformation.Load(playlistID); ok {
var playlist = p.(Playlist) var playlist = p.(Playlist)
@@ -493,6 +499,8 @@ func killClientConnection(streamID int, playlistID string, force bool) {
func clientConnection(stream ThisStream) (status bool) { func clientConnection(stream ThisStream) (status bool) {
status = true status = true
Lock.Lock()
defer Lock.Unlock()
if _, ok := BufferClients.Load(stream.PlaylistID + stream.MD5); !ok { if _, ok := BufferClients.Load(stream.PlaylistID + stream.MD5); !ok {
@@ -901,6 +909,8 @@ func connectToStreamingServer(streamID int, playlistID string) {
// Buffer auf die Festplatte speichern // Buffer auf die Festplatte speichern
if fileSize >= tmpFileSize/2 || n == 0 { if fileSize >= tmpFileSize/2 || n == 0 {
Lock.Lock()
bandwidth.Stop = time.Now() bandwidth.Stop = time.Now()
bandwidth.Size += fileSize bandwidth.Size += fileSize
@@ -919,6 +929,7 @@ func connectToStreamingServer(streamID int, playlistID string) {
stream.Status = true stream.Status = true
playlist.Streams[streamID] = stream playlist.Streams[streamID] = stream
BufferInformation.Store(playlistID, playlist) BufferInformation.Store(playlistID, playlist)
Lock.Unlock()
tmpSegment++ tmpSegment++
@@ -1408,8 +1419,37 @@ func thirdPartyBuffer(streamID int, playlistID string) {
return return
} }
var args = strings.Replace(options, "[URL]", url, -1) //args = strings.Replace(args, "[USER-AGENT]", Settings.UserAgent, -1)
var cmd = exec.Command(path, strings.Split(args, " ")...)
// User-Agent setzen
var args []string
for i, a := range strings.Split(options, " ") {
switch bufferType {
case "FFMPEG":
a = strings.Replace(a, "[URL]", url, -1)
if i == 0 {
args = []string{"-user-agent", Settings.UserAgent}
}
args = append(args, a)
case "VLC":
if a == "[URL]" {
a = strings.Replace(a, "[URL]", url, -1)
args = append(args, a)
args = append(args, fmt.Sprintf(":http-user-agent=%s", Settings.UserAgent))
} else {
args = append(args, a)
}
}
}
var cmd = exec.Command(path, args...)
debug = fmt.Sprintf("%s:%s %s", bufferType, path, args) debug = fmt.Sprintf("%s:%s %s", bufferType, path, args)
showDebug(debug, 1) showDebug(debug, 1)
@@ -1551,9 +1591,11 @@ func thirdPartyBuffer(streamID int, playlistID string) {
tmpSegment++ tmpSegment++
if stream.Status == false { if stream.Status == false {
Lock.Lock()
stream.Status = true stream.Status = true
playlist.Streams[streamID] = stream playlist.Streams[streamID] = stream
BufferInformation.Store(playlistID, playlist) BufferInformation.Store(playlistID, playlist)
Lock.Unlock()
} }
tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment) tmpFile = fmt.Sprintf("%s%d.ts", tmpFolder, tmpSegment)

View File

@@ -29,6 +29,9 @@ var BufferInformation sync.Map
// BufferClients : Anzahl der Clients die einen Stream über den Buffer abspielen // BufferClients : Anzahl der Clients die einen Stream über den Buffer abspielen
var BufferClients sync.Map var BufferClients sync.Map
// Lock : Lock Map
var Lock = sync.RWMutex{}
// Init : Systeminitialisierung // Init : Systeminitialisierung
func Init() (err error) { func Init() (err error) {
@@ -220,6 +223,8 @@ func StartSystem(updateProviderFiles bool) (err error) {
return return
} }
setURLScheme()
// Systeminformationen in der Konsole ausgeben // Systeminformationen in der Konsole ausgeben
showInfo(fmt.Sprintf("UUID:%s", Settings.UUID)) showInfo(fmt.Sprintf("UUID:%s", Settings.UUID))
showInfo(fmt.Sprintf("Tuner (Plex / Emby):%d", Settings.Tuner)) showInfo(fmt.Sprintf("Tuner (Plex / Emby):%d", Settings.Tuner))

View File

@@ -107,6 +107,9 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
} }
case "scheme.m3u", "scheme.xml":
createXEPGFiles = true
} }
oldSettings[key] = value oldSettings[key] = value
@@ -141,6 +144,8 @@ func updateServerSettings(request RequestStruct) (settings SettingsStrcut, err e
return return
} }
setURLScheme()
if Settings.AuthenticationWEB == false { if Settings.AuthenticationWEB == false {
Settings.AuthenticationAPI = false Settings.AuthenticationAPI = false
@@ -505,7 +510,7 @@ func saveXEpgMapping(request RequestStruct) (err error) {
System.ScanInProgress = 1 System.ScanInProgress = 1
cleanupXEPG() cleanupXEPG()
//buildXEPG(true) buildXEPG(true)
go func() { go func() {
@@ -540,8 +545,7 @@ func saveXEpgMapping(request RequestStruct) (err error) {
System.ScanInProgress = 1 System.ScanInProgress = 1
cleanupXEPG() cleanupXEPG()
//buildXEPG(false) buildXEPG(false)
createXMLTVFile() createXMLTVFile()
createM3UFile() createM3UFile()
showInfo("XEPG:" + fmt.Sprintf("Ready to use")) showInfo("XEPG:" + fmt.Sprintf("Ready to use"))

View File

@@ -45,7 +45,7 @@ func getCacheImageURL(imageURL string) (cacheImageURL string) {
if indexOfString(urlMD5+fileExtension, Data.Cache.ImagesCache) != -1 { if indexOfString(urlMD5+fileExtension, Data.Cache.ImagesCache) != -1 {
cacheImageURL = fmt.Sprintf("%s://%s/images/%s%s", System.ServerProtocol.WEB, System.Domain, urlMD5, fileExtension) cacheImageURL = fmt.Sprintf("%s://%s/images/%s%s", System.ServerProtocol.XML, System.Domain, urlMD5, fileExtension)
} else { } else {
@@ -163,7 +163,7 @@ func uploadLogo(input, filename string) (logoURL string, err error) {
return return
} }
logoURL = fmt.Sprintf("%s://%s/data_images/%s", System.ServerProtocol.WEB, System.Domain, filename) logoURL = fmt.Sprintf("%s://%s/data_images/%s", System.ServerProtocol.XML, System.Domain, filename)
return return

View File

@@ -187,6 +187,7 @@ type XEPGChannelStruct struct {
XName string `json:"x-name,required"` XName string `json:"x-name,required"`
XUpdateChannelIcon bool `json:"x-update-channel-icon,required"` XUpdateChannelIcon bool `json:"x-update-channel-icon,required"`
XUpdateChannelName bool `json:"x-update-channel-name,required"` XUpdateChannelName bool `json:"x-update-channel-name,required"`
XDescription string `json:"x-description,required"`
} }
// M3UChannelStructXEPG : M3U Struktur für XEPG // M3UChannelStructXEPG : M3U Struktur für XEPG
@@ -279,6 +280,8 @@ type SettingsStrcut struct {
MappingFirstChannel float64 `json:"mapping.first.channel"` MappingFirstChannel float64 `json:"mapping.first.channel"`
Port string `json:"port"` Port string `json:"port"`
SSDP bool `json:"ssdp"` SSDP bool `json:"ssdp"`
SchemeM3U string `json:"scheme.m3u"`
SchemeXML string `json:"scheme.xml"`
TempPath string `json:"temp.path"` TempPath string `json:"temp.path"`
Tuner int `json:"tuner"` Tuner int `json:"tuner"`
Update []string `json:"update"` Update []string `json:"update"`

View File

@@ -41,6 +41,8 @@ type RequestStruct struct {
UserAgent *string `json:"user.agent,omitempty"` UserAgent *string `json:"user.agent,omitempty"`
XepgReplaceMissingImages *bool `json:"xepg.replace.missing.images,omitempty"` XepgReplaceMissingImages *bool `json:"xepg.replace.missing.images,omitempty"`
XteveAutoUpdate *bool `json:"xteveAutoUpdate,omitempty"` XteveAutoUpdate *bool `json:"xteveAutoUpdate,omitempty"`
SchemeM3U *string `json:"scheme.m3u,omitempty"`
SchemeXML *string `json:"scheme.xml,omitempty"`
} `json:"settings,omitempty"` } `json:"settings,omitempty"`
// Upload Logo // Upload Logo

View File

@@ -48,6 +48,7 @@ type Program struct {
PreviouslyShown *PreviouslyShown `xml:"previously-shown"` PreviouslyShown *PreviouslyShown `xml:"previously-shown"`
New *New `xml:"new"` New *New `xml:"new"`
Live *Live `xml:"live"` Live *Live `xml:"live"`
Premiere *Live `xml:"premiere"`
} }
// Title : Programmtitel // Title : Programmtitel

View File

@@ -138,6 +138,8 @@ func loadSettings() (settings SettingsStrcut, err error) {
defaults["version"] = System.DBVersion defaults["version"] = System.DBVersion
defaults["xteveAutoUpdate"] = true defaults["xteveAutoUpdate"] = true
defaults["temp.path"] = System.Folder.Temp defaults["temp.path"] = System.Folder.Temp
defaults["scheme.M3U"] = "HTTP"
defaults["scheme.XML"] = "HTTP"
// Default Werte setzen // Default Werte setzen
for key, value := range defaults { for key, value := range defaults {
@@ -252,6 +254,14 @@ func setGlobalDomain(domain string) {
return return
} }
func setURLScheme() {
System.ServerProtocol.M3U = strings.ToLower(Settings.SchemeM3U)
System.ServerProtocol.XML = strings.ToLower(Settings.SchemeXML)
return
}
// UUID generieren // UUID generieren
func createUUID() (uuid string) { func createUUID() (uuid string) {
uuid = time.Now().Format("2006-01") + "-" + randomString(4) + "-" + randomString(6) uuid = time.Now().Format("2006-01") + "-" + randomString(4) + "-" + randomString(6)

File diff suppressed because one or more lines are too long

View File

@@ -132,7 +132,7 @@ func Stream(w http.ResponseWriter, r *http.Request) {
switch Settings.Buffer { switch Settings.Buffer {
case "-": case "-":
showInfo(fmt.Sprintf("Buffer:false", Settings.Buffer)) showInfo(fmt.Sprintf("Buffer:false [%s]", Settings.Buffer))
case "xteve": case "xteve":
if strings.Index(streamInfo.URL, "rtsp://") != -1 || strings.Index(streamInfo.URL, "rtp://") != -1 { if strings.Index(streamInfo.URL, "rtsp://") != -1 || strings.Index(streamInfo.URL, "rtp://") != -1 {
@@ -316,10 +316,12 @@ func WS(w http.ResponseWriter, r *http.Request) {
var newToken string var newToken string
if r.Header.Get("Origin") != "http://"+r.Host { /*
httpStatusError(w, r, 403) if r.Header.Get("Origin") != "http://"+r.Host {
return httpStatusError(w, r, 403)
} return
}
*/
conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024) conn, err := websocket.Upgrade(w, r, w.Header(), 1024, 1024)
if err != nil { if err != nil {

View File

@@ -717,6 +717,9 @@ func getProgramData(xepgChannel XEPGChannelStruct) (xepgXML XMLTV, err error) {
// Live // Live
program.Live = xmltvProgram.Live program.Live = xmltvProgram.Live
// Premiere
program.Premiere = xmltvProgram.Premiere
xepgXML.Program = append(xepgXML.Program, program) xepgXML.Program = append(xepgXML.Program, program)
} }
@@ -759,7 +762,12 @@ func createDummyProgram(xepgChannel XEPGChannelStruct) (dummyXMLTV XMLTV) {
epg.Start = epgStartTime.Format("20060102150405") + offset epg.Start = epgStartTime.Format("20060102150405") + offset
epg.Stop = epgStopTime.Format("20060102150405") + offset epg.Stop = epgStopTime.Format("20060102150405") + offset
epg.Title = append(epg.Title, &Title{Value: xepgChannel.XName + " (" + epgStartTime.Weekday().String()[0:2] + ". " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04") + ")", Lang: "en"}) epg.Title = append(epg.Title, &Title{Value: xepgChannel.XName + " (" + epgStartTime.Weekday().String()[0:2] + ". " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04") + ")", Lang: "en"})
epg.Desc = append(epg.Desc, &Desc{Value: "xTeVe: (" + strconv.Itoa(dummyLength) + " Minutes) " + epgStartTime.Weekday().String() + " " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04"), Lang: "en"})
if len(xepgChannel.XDescription) == 0 {
epg.Desc = append(epg.Desc, &Desc{Value: "xTeVe: (" + strconv.Itoa(dummyLength) + " Minutes) " + epgStartTime.Weekday().String() + " " + epgStartTime.Format("15:04") + " - " + epgStopTime.Format("15:04"), Lang: "en"})
} else {
epg.Desc = append(epg.Desc, &Desc{Value: xepgChannel.XDescription, Lang: "en"})
}
if Settings.XepgReplaceMissingImages == true { if Settings.XepgReplaceMissingImages == true {
poster.Src = getCacheImageURL(xepgChannel.TvgLogo) poster.Src = getCacheImageURL(xepgChannel.TvgLogo)

View File

@@ -21,7 +21,7 @@ menuItems.push(new MainMenuItem("logout", "{{.mainMenu.item.logout}}", "logout.p
// Kategorien für die Einstellungen // Kategorien für die Einstellungen
var settingsCategory = new Array() var settingsCategory = new Array()
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api")) settingsCategory.push(new SettingsCategoryItem("{{.settings.category.general}}", "xteveAutoUpdate,tuner,epgSource,api,scheme.m3u,scheme.xml"))
settingsCategory.push(new SettingsCategoryItem("{{.settings.category.files}}", "update,files.update,temp.path,cache.images,xepg.replace.missing.images")) 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,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.backup}}", "backup.path,backup.keep"))

View File

@@ -1532,6 +1532,13 @@ function openPopUp(dataType, element) {
content.description(data["name"]) content.description(data["name"])
// Beschreibung
var dbKey:string = "x-description"
var input = content.createInput("text", dbKey, data[dbKey])
input.setAttribute("placeholder", "{{.mapping.description.placeholder}}")
input.setAttribute("onchange", "javascript: this.className = 'changed'")
content.appendRow("{{.mapping.description.title}}", input)
// Aktualisierung des Kanalnamens // Aktualisierung des Kanalnamens
if (data.hasOwnProperty("_uuid.key")) { if (data.hasOwnProperty("_uuid.key")) {
if (data["_uuid.key"] != "") { if (data["_uuid.key"] != "") {

View File

@@ -372,6 +372,38 @@ class SettingsCategory {
setting.appendChild(tdRight) setting.appendChild(tdRight)
break break
case "scheme.m3u":
var tdLeft = document.createElement("TD")
tdLeft.innerHTML = "{{.settings.schemeM3U.title}}" + ":"
var tdRight = document.createElement("TD")
var text:any[] = ["HTTP", "HTTPS"]
var values:any[] = ["HTTP", "HTTPS"]
var select = content.createSelect(text, values, data, settingsKey)
select.setAttribute("onchange", "javascript: this.className = 'changed'")
tdRight.appendChild(select)
setting.appendChild(tdLeft)
setting.appendChild(tdRight)
break
case "scheme.xml":
var tdLeft = document.createElement("TD")
tdLeft.innerHTML = "{{.settings.schemeXML.title}}" + ":"
var tdRight = document.createElement("TD")
var text:any[] = ["HTTP", "HTTPS"]
var values:any[] = ["HTTP", "HTTPS"]
var select = content.createSelect(text, values, data, settingsKey)
select.setAttribute("onchange", "javascript: this.className = 'changed'")
tdRight.appendChild(select)
setting.appendChild(tdLeft)
setting.appendChild(tdRight)
break
} }
return setting return setting
@@ -483,6 +515,15 @@ class SettingsCategory {
text = "{{.settings.replaceEmptyImages.description}}" text = "{{.settings.replaceEmptyImages.description}}"
break break
case "scheme.m3u":
text = "{{.settings.schemeM3U.description}}"
break
case "scheme.xml":
text = "{{.settings.schemeXML.description}}"
break
default: default:
text = "" text = ""
break break

View File

@@ -39,7 +39,7 @@ var GitHub = GitHubStruct{Branch: "master", User: "xteve-project", Repo: "xTeVe-
const Name = "xTeVe" const Name = "xTeVe"
// Version : Version, die Build Nummer wird in der main func geparst. // Version : Version, die Build Nummer wird in der main func geparst.
const Version = "2.1.0.0100" const Version = "2.1.1.0111"
// DBVersion : Datanbank Version // DBVersion : Datanbank Version
const DBVersion = "2.1.0" const DBVersion = "2.1.0"