mlbserver 2024.10.7 → 2024.10.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +105 -32
  2. package/package.json +1 -1
  3. package/session.js +26 -9
package/index.js CHANGED
@@ -29,12 +29,12 @@ const VALID_CONTROLS = [ 'Show', 'Hide' ]
29
29
  const VALID_INNING_HALF = [ '', 'top', 'bottom' ]
30
30
  const VALID_INNING_NUMBER = [ '', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12' ]
31
31
  const VALID_SCORES = [ 'Hide', 'Show' ]
32
- const VALID_RESOLUTIONS = [ 'adaptive', '720p60', '720p', '540p', '504p', '360p', 'none' ]
32
+ const VALID_RESOLUTIONS = [ 'adaptive', '720p60', '720p', '540p', '504p', '360p', 'none' ]
33
33
  const DEFAULT_MULTIVIEW_RESOLUTION = '504p'
34
34
  // Corresponding andwidths to display for above resolutions
35
35
  const DISPLAY_BANDWIDTHS = [ '', '6600k', '4160k', '2950k', '2120k', '1400k', '' ]
36
- const VALID_AUDIO_TRACKS = [ 'all', 'English', 'Home Radio', 'Casa Radio', 'Away Radio', 'Visita Radio', 'none' ]
37
- const DISPLAY_AUDIO_TRACKS = [ 'all', 'TV', 'Radio', 'Spanish', 'Away Radio', 'Away Sp.', 'none' ]
36
+ const VALID_AUDIO_TRACKS = [ 'all', 'English', 'Home Radio', 'Casa Radio', 'Away Radio', 'Visita Radio', 'Park', 'none' ]
37
+ const DISPLAY_AUDIO_TRACKS = [ 'all', 'TV', 'Radio', 'Spa.', 'Away Rad.', 'Away Sp.', 'Park', 'none' ]
38
38
  const DEFAULT_MULTIVIEW_AUDIO_TRACK = 'English'
39
39
  const VALID_SKIP = [ 'off', 'breaks', 'idle time', 'pitches', 'commercials' ]
40
40
  const DEFAULT_SKIP_ADJUST = 0
@@ -528,23 +528,28 @@ function getMasterPlaylist(streamURL, req, res, options = {}) {
528
528
  if ( audio_track_matched ) return
529
529
 
530
530
  // user specified no audio tracks
531
- if ( audio_track == VALID_AUDIO_TRACKS[VALID_AUDIO_TRACKS.length-1] ) {
531
+ /*if ( audio_track == VALID_AUDIO_TRACKS[VALID_AUDIO_TRACKS.length-1] ) {
532
532
  audio_track_matched = true
533
533
  return
534
- }
534
+ }*/
535
535
 
536
536
  // we'll append to this and output track(s) at the end of this code block
537
537
  let audio_output = ''
538
538
 
539
- // default TV audio
539
+ // default TV audio, or park sounds
540
540
  if ( !line.includes(',URI=') ) {
541
- if ( audio_track == VALID_AUDIO_TRACKS[1] ) {
541
+ // only include default embedded audio track if requested or if filtering for park audio
542
+ if ( (audio_track == VALID_AUDIO_TRACKS[1]) || (audio_track == VALID_AUDIO_TRACKS[6]) ) {
543
+ audio_track_matched = true
544
+ if ( audio_track == VALID_AUDIO_TRACKS[6] ) {
545
+ line = line.replace('English','Park Sounds')
546
+ }
542
547
  return line
543
548
  } else if ( audio_track == VALID_AUDIO_TRACKS[0] ) {
544
549
  audio_output += line
545
550
  }
546
551
  } else {
547
- if ( (audio_track == VALID_AUDIO_TRACKS[0]) || (audio_track == VALID_AUDIO_TRACKS[2]) || (audio_track == VALID_AUDIO_TRACKS[3]) || (audio_track == VALID_AUDIO_TRACKS[4]) || (audio_track == VALID_AUDIO_TRACKS[5]) ) {
552
+ if ( (audio_track != VALID_AUDIO_TRACKS[1]) && (audio_track != VALID_AUDIO_TRACKS[6]) && (audio_track != VALID_AUDIO_TRACKS[7]) ) {
548
553
  // if user specified home/away radio or home/away Spanish audio track, check if this one matches
549
554
  if ( (audio_track == VALID_AUDIO_TRACKS[2]) || (audio_track == VALID_AUDIO_TRACKS[3]) || (audio_track == VALID_AUDIO_TRACKS[4]) || (audio_track == VALID_AUDIO_TRACKS[5]) ) {
550
555
  if ( line.includes('NAME="'+audio_track+'"') || line.includes('NAME="'+audio_track.substring(0,audio_track.length-1)+'"') ) {
@@ -637,6 +642,7 @@ function getMasterPlaylist(streamURL, req, res, options = {}) {
637
642
  if ( skip_adjust != DEFAULT_SKIP_ADJUST ) newurl += '&skip_adjust=' + skip_adjust
638
643
  if ( pad != VALID_PAD[0] ) newurl += '&pad=' + pad
639
644
  if ( gamePk ) newurl += '&gamePk=' + gamePk
645
+ if ( audio_track != VALID_AUDIO_TRACKS[0] ) newurl += '&audio_track=' + encodeURIComponent(audio_track)
640
646
  newurl += content_protect + referer_parameter + token_parameter
641
647
  return '/playlist?url='+newurl
642
648
  }
@@ -693,6 +699,7 @@ app.get('/playlist', async function(req, res) {
693
699
  var skip_adjust = req.query.skip_adjust || DEFAULT_SKIP_ADJUST
694
700
  var pad = req.query.pad || VALID_PAD[0]
695
701
  var gamePk = req.query.gamePk || false
702
+ var audio_track = req.query.audio_track || VALID_AUDIO_TRACKS[0]
696
703
 
697
704
  var req = function () {
698
705
  var headers = {}
@@ -817,6 +824,11 @@ app.get('/playlist', async function(req, res) {
817
824
  newline += '?url='+encodeURIComponent(url.resolve(u, line.trim())) + content_protect + referer_parameter + token_parameter
818
825
  if ( key ) newline += '&key='+encodeURIComponent(key) + '&iv='+encodeURIComponent(iv)
819
826
 
827
+ // if an alternate audio track is specified, force removal of embedded audio
828
+ if ( (audio_track != VALID_AUDIO_TRACKS[0]) && (audio_track != VALID_AUDIO_TRACKS[1]) ) {
829
+ newline = 'download.html?audio_track=' + encodeURIComponent(audio_track) + '&src=' + encodeURIComponent('http://127.0.0.1:' + session.data.port + newline) + content_protect
830
+ }
831
+
820
832
  return newline
821
833
  })
822
834
  .filter(function(line) {
@@ -1532,13 +1544,13 @@ app.get('/', async function(req, res) {
1532
1544
  if ( resolution != VALID_RESOLUTIONS[0] ) querystring += '&resolution=' + resolution
1533
1545
  if ( linkType == VALID_LINK_TYPES[1] ) {
1534
1546
  if ( force_vod != VALID_FORCE_VOD[0] ) querystring += '&force_vod=' + force_vod
1535
- } else if ( linkType == VALID_LINK_TYPES[VALID_LINK_TYPES.length-1] ) {
1547
+ } else if ( linkType == VALID_LINK_TYPES[4] ) {
1536
1548
  querystring += '&filename=' + gameDate + ' MLB Network'
1537
1549
  }
1538
1550
  querystring += content_protect_b
1539
1551
  multiviewquerystring += content_protect_b
1540
1552
  body += '<a href="' + thislink + querystring + '">MLB Network</a>'
1541
- body += '<input type="checkbox" value="' + server + '/stream.m3u8' + multiviewquerystring + '" onclick="addmultiview(this)">'
1553
+ body += '<input type="checkbox" value="http://127.0.0.1:' + session.data.port + '/stream.m3u8' + multiviewquerystring + '" onclick="addmultiview(this)">'
1542
1554
  body += '</td></tr>' + "\n"
1543
1555
  } // end entitlements check
1544
1556
  } // end country check
@@ -1590,13 +1602,13 @@ app.get('/', async function(req, res) {
1590
1602
  if ( resolution != VALID_RESOLUTIONS[0] ) querystring += '&resolution=' + resolution
1591
1603
  if ( linkType == VALID_LINK_TYPES[1] ) {
1592
1604
  if ( force_vod != VALID_FORCE_VOD[0] ) querystring += '&force_vod=' + force_vod
1593
- } else if ( linkType == VALID_LINK_TYPES[VALID_LINK_TYPES.length-1] ) {
1605
+ } else if ( linkType == VALID_LINK_TYPES[4] ) {
1594
1606
  querystring += '&filename=' + gameDate + ' Big Inning'
1595
1607
  }
1596
1608
  querystring += content_protect_b
1597
1609
  multiviewquerystring += content_protect_b
1598
1610
  body += '<a href="' + thislink + querystring + '">Big Inning</a>'
1599
- body += '<input type="checkbox" value="' + server + '/stream.m3u8' + multiviewquerystring + '" onclick="addmultiview(this)">'
1611
+ body += '<input type="checkbox" value="http://127.0.0.1:' + session.data.port + '/stream.m3u8' + multiviewquerystring + '" onclick="addmultiview(this)">'
1600
1612
  } else {
1601
1613
  body += 'Big Inning'
1602
1614
  }
@@ -1623,11 +1635,11 @@ app.get('/', async function(req, res) {
1623
1635
  if ( linkType != VALID_LINK_TYPES[1] ) {
1624
1636
  streamURL = thislink + '?src=' + encodeURIComponent(streamURL) + '&startFrom=' + VALID_START_FROM[1] + content_protect_b
1625
1637
  }
1626
- if ( linkType == VALID_LINK_TYPES[VALID_LINK_TYPES.length-1] ) {
1638
+ if ( linkType == VALID_LINK_TYPES[4] ) {
1627
1639
  streamURL += '&filename=' + gameDate + ' Game Changer'
1628
1640
  }
1629
1641
  body += '<a href="' + streamURL + '">Game Changer</a>'
1630
- body += '<input type="checkbox" value="' + multiviewquerystring + '" onclick="addmultiview(this, [], excludeTeams)">'
1642
+ body += '<input type="checkbox" value="http://127.0.0.1:' + session.data.port + multiviewquerystring + '" onclick="addmultiview(this, [], excludeTeams)">'
1631
1643
  } else {
1632
1644
  body += 'Game Changer'
1633
1645
  }
@@ -1876,13 +1888,13 @@ app.get('/', async function(req, res) {
1876
1888
  if ( currentTime < endTime ) {
1877
1889
  if ( force_vod != VALID_FORCE_VOD[0] ) querystring += '&force_vod=' + force_vod
1878
1890
  }
1879
- } else if ( linkType == VALID_LINK_TYPES[VALID_LINK_TYPES.length-1] ) {
1891
+ } else if ( linkType == VALID_LINK_TYPES[4] ) {
1880
1892
  querystring += '&filename=' + filename + broadcastName
1881
1893
  }
1882
1894
  querystring += content_protect_b
1883
1895
  multiviewquerystring += content_protect_b
1884
1896
  body += '<a href="' + thislink + querystring + '">' + broadcastName + '</a>'
1885
- body += '<input type="checkbox" value="' + server + '/stream.m3u8' + multiviewquerystring + '" onclick="addmultiview(this)">'
1897
+ body += '<input type="checkbox" value="http://127.0.0.1:' + session.data.port + '/stream.m3u8' + multiviewquerystring + '" onclick="addmultiview(this)">'
1886
1898
  } else {
1887
1899
  body += broadcastName
1888
1900
  }
@@ -1971,7 +1983,7 @@ app.get('/', async function(req, res) {
1971
1983
  if ( broadcast.mediaState.mediaStateCode == 'MEDIA_ON' ) {
1972
1984
  if ( force_vod != VALID_FORCE_VOD[0] ) querystring += '&force_vod=' + force_vod
1973
1985
  }
1974
- } else if ( linkType == VALID_LINK_TYPES[VALID_LINK_TYPES.length-1] ) {
1986
+ } else if ( linkType == VALID_LINK_TYPES[4] ) {
1975
1987
  querystring += '&filename=' + filename + station
1976
1988
  }
1977
1989
  querystring += content_protect_b
@@ -1984,7 +1996,7 @@ app.get('/', async function(req, res) {
1984
1996
  body += stationlink
1985
1997
  }
1986
1998
  if ( mediaType == 'MLBTV' ) {
1987
- body += '<input type="checkbox" value="' + server + '/stream.m3u8' + multiviewquerystring + '" onclick="addmultiview(this, [\'' + awayteam + '\', \'' + hometeam + '\'])">'
1999
+ body += '<input type="checkbox" value="http://127.0.0.1:' + session.data.port + '/stream.m3u8' + multiviewquerystring + '" onclick="addmultiview(this, [\'' + awayteam + '\', \'' + hometeam + '\'])">'
1988
2000
  }
1989
2001
  if ( resumeStatus ) {
1990
2002
  body += '('
@@ -2949,12 +2961,17 @@ app.get('/kodi.strm', async function(req, res) {
2949
2961
  }
2950
2962
  })
2951
2963
 
2952
- // Listen for download requests
2964
+ // Listen for download requests (either for actual downloads or just proxying stream through ffmpeg)
2953
2965
  app.get('/download.html', async function(req, res) {
2954
2966
  if ( ! (await protect(req, res)) ) return
2955
2967
 
2956
2968
  try {
2957
- session.requestlog('download', req)
2969
+ // we'll know it's an actual download request if it include a filename parameter
2970
+ if ( req.query.filename ) {
2971
+ session.requestlog('download', req)
2972
+ } else {
2973
+ session.debuglog('force alternate audio', req)
2974
+ }
2958
2975
 
2959
2976
  let server = 'http://' + req.headers.host
2960
2977
 
@@ -2970,26 +2987,85 @@ app.get('/download.html', async function(req, res) {
2970
2987
  }
2971
2988
  session.debuglog('download src : ' + video_url)
2972
2989
 
2990
+ // force adaptive streams to just use a single video resolution/track
2991
+ if ( req.query.filename ) {
2992
+ if ( !video_url.includes('resolution') ) {
2993
+ video_url += '&resolution=best'
2994
+ } else if ( video_url.includes('resolution=adaptive') ) {
2995
+ video_url = video_url.replace('resolution=adaptive', 'resolution=best')
2996
+ }
2997
+ }
2998
+
2973
2999
  ffmpeg_command = ffmpeg({ timeout: 432000 })
2974
3000
 
2975
- // Set input stream and its thread queue size
3001
+ // Set input stream and minimize ffmpeg startup latency
2976
3002
  ffmpeg_command.input(video_url)
2977
- .addOutputOption('-c', 'copy')
2978
- .addOutputOption('-f', 'mpegts')
3003
+ .addInputOption('-fflags', 'nobuffer')
3004
+ .addInputOption('-probesize', '32')
3005
+ .addInputOption('-analyzeduration', '0')
3006
+
3007
+ // video
3008
+ if ( !req.query.resolution || (req.query.resolution != VALID_RESOLUTIONS[VALID_RESOLUTIONS.length-1]) ) {
3009
+ // copy first video track if available
3010
+ ffmpeg_command.addOutputOption('-map', '0:v:0?')
3011
+ .addOutputOption('-c:v', 'copy')
3012
+ } else {
3013
+ // suppress video is "none" resolution was specified
3014
+ ffmpeg_command.addOutputOption('-vn')
3015
+ }
3016
+
3017
+ // audio
3018
+ if ( !req.query.audio_track || (req.query.audio_track == VALID_AUDIO_TRACKS[0]) ) {
3019
+ // if no specific audio track was requested, include and copy them all
3020
+ ffmpeg_command.addOutputOption('-map', '0:a')
3021
+ .addOutputOption('-c:a', 'copy')
3022
+ } else {
3023
+ // park sounds audio track
3024
+ if ( req.query.audio_track == VALID_AUDIO_TRACKS[6] ) {
3025
+ // filter for park audio track
3026
+ ffmpeg_command.complexFilter([{
3027
+ filter: 'pan=stereo|c0=c0|c1=-1*c1',
3028
+ inputs: '0:a:0',
3029
+ outputs: 'out0'
3030
+ }])
3031
+ // map filtered audio and re-encode to mono
3032
+ ffmpeg_command.addOutputOption('-map', '[out0]')
3033
+ .addOutputOption('-c:a', 'aac')
3034
+ .addOutputOption('-ac:a:0', '1')
3035
+
3036
+ // if not downloading to a file, also copy source PTS values for continuous playback
3037
+ if ( !req.query.filename ) {
3038
+ ffmpeg_command.addOutputOption('-copyts')
3039
+ .addOutputOption('-muxpreload', '0')
3040
+ .addOutputOption('-muxdelay', '0')
3041
+ }
3042
+ } else if ( (!req.query.filename && (req.query.audio_track != VALID_AUDIO_TRACKS[1])) || (req.query.audio_track == VALID_AUDIO_TRACKS[7]) ) {
3043
+ // if we're not downloading a file, and we requested an alternate audio track, then we want to suppress the embedded TV audio
3044
+ // or if the user requested no audio tracks in their download, we will suppress all
3045
+ ffmpeg_command.addOutputOption('-an')
3046
+ } else {
3047
+ // fallback to only including and copying first audio track
3048
+ ffmpeg_command.addOutputOption('-map', '0:a:0')
3049
+ .addOutputOption('-c:a', 'copy')
3050
+ }
3051
+ }
3052
+
3053
+ // output mpegts to response stream
3054
+ ffmpeg_command.addOutputOption('-f', 'mpegts')
2979
3055
  .output(res)
2980
3056
  .on('start', function(commandLine) {
2981
- session.log('download command started')
3057
+ session.debuglog('download command started')
2982
3058
  if ( argv.debug || argv.ffmpeg_logging ) {
2983
- session.log('download command: ' + commandLine)
3059
+ session.debuglog('download command: ' + commandLine)
2984
3060
  }
2985
3061
  })
2986
3062
  .on('error', function(err, stdout, stderr) {
2987
- session.log('download command stopped: ' + err.message)
3063
+ session.debuglog('download command stopped: ' + err.message)
2988
3064
  if ( stdout ) session.log(stdout)
2989
3065
  if ( stderr ) session.log(stderr)
2990
3066
  })
2991
3067
  .on('end', function() {
2992
- session.log('download command ended')
3068
+ session.debuglog('download command ended')
2993
3069
  })
2994
3070
 
2995
3071
  if ( argv.ffmpeg_logging ) {
@@ -2999,12 +3075,9 @@ app.get('/download.html', async function(req, res) {
2999
3075
  })
3000
3076
  }
3001
3077
 
3002
- var filename = 'mlbserver'
3078
+ var download_headers = {}
3003
3079
  if ( req.query.filename ) {
3004
- filename = req.query.filename
3005
- }
3006
- var download_headers = {
3007
- 'Content-Disposition': 'attachment; filename="' + filename + '.ts"'
3080
+ download_headers['Content-Disposition'] = 'attachment; filename="' + req.query.filename + '.ts"'
3008
3081
  }
3009
3082
  res.writeHead(200, download_headers)
3010
3083
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mlbserver",
3
- "version": "2024.10.07",
3
+ "version": "2024.10.10",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
package/session.js CHANGED
@@ -26,6 +26,8 @@ const TODAY_UTC_HOURS = 8 // UTC hours (EST + 4) into tomorrow to still use toda
26
26
 
27
27
  const TEAM_IDS = { 'ATL': '144', 'AZ': '109', 'BAL': '110', 'BOS': '111', 'CHC': '112', 'CWS': '145', 'CIN': '113', 'CLE': '114', 'COL': '115', 'DET': '116', 'HOU': '117', 'KC': '118', 'LAA': '108', 'LAD': '119', 'MIA': '146', 'MIL': '158', 'MIN': '142', 'NYM': '121', 'NYY': '147', 'OAK': '133', 'PHI': '143', 'PIT': '134', 'STL': '138', 'SD': '135', 'SF': '137', 'SEA': '136', 'TB': '139', 'TEX': '140', 'TOR': '141', 'WSH': '120' }
28
28
 
29
+ const LIDOM_TEAM_IDS = { 'AGU': '667', 'TOR': '668', 'EST': '669', 'GIG': '670', 'ESC': '671', 'LIC': '672' }
30
+
29
31
  const AFFILIATE_TEAM_IDS = { 'ATL': '430,431,432,478', 'AZ': '419,516,2310,5368', 'BAL': '418,488,548,568', 'BOS': '414,428,533,546', 'CHC': '451,521,550,553', 'CIN': '416,450,459,498', 'CLE': '402,437,445,481', 'COL': '259,342,486,538', 'CWS': '247,487,494,580', 'DET': '106,512,570,582', 'HOU': '482,573,3712,5434', 'KC': '541,565,1350,3705', 'LAA': '401,460,559,561', 'LAD': '238,260,456,526', 'MIA': '479,554,564,4124', 'MIL': '249,556,572,5015', 'MIN': '492,509,1960,3898', 'NYM': '453,505,507,552', 'NYY': '531,537,587,1956', 'OAK': '237,400,499,524', 'PHI': '427,522,566,1410', 'PIT': '452,477,484,3390', 'SD': '103,510,584,4904', 'SEA': '403,515,529,574', 'SF': '105,461,476,3410', 'STL': '235,279,440,443', 'TB': '233,234,421,2498', 'TEX': '102,448,485,540', 'TOR': '422,424,435,463', 'WSH': '426,436,534,547' }
30
32
 
31
33
  // Other country options would be USA, Canada, or other
@@ -1136,6 +1138,14 @@ class sessionClass {
1136
1138
  }
1137
1139
  }
1138
1140
 
1141
+ getLidomTeamIds(team_abbr = false) {
1142
+ if ( team_abbr ) {
1143
+ return LIDOM_TEAM_IDS[team_abbr]
1144
+ } else {
1145
+ return Object.values(LIDOM_TEAM_IDS).toString()
1146
+ }
1147
+ }
1148
+
1139
1149
  getAffiliateTeamIds(team_abbr = false) {
1140
1150
  if ( team_abbr ) {
1141
1151
  return AFFILIATE_TEAM_IDS[team_abbr]
@@ -1797,10 +1807,10 @@ class sessionClass {
1797
1807
  this.debuglog('checking game ' + cache_data.dates[0].games[j].teams['home'].team.abbreviation + '@' + cache_data.dates[0].games[j].teams['away'].team.abbreviation)
1798
1808
 
1799
1809
  // check that that game involves the requested team, or if we've requested a national or free game
1800
- if ( ((team.toUpperCase() == home_team) && (LEVELS[level.toUpperCase()] == home_level)) || ((team.toUpperCase() == away_team) && (LEVELS[level.toUpperCase()] == away_level)) || (team.toUpperCase().indexOf('NATIONAL.') == 0) || ((team.toUpperCase().startsWith('FREE.') && cache_data.dates[0].games[j].broadcasts && cache_data.dates[0].games[j].broadcasts[0] && (cache_data.dates[0].games[j].broadcasts[0].freeGame == true))) ) {
1810
+ if ( ((team.toUpperCase() == home_team) && (LEVELS[level.toUpperCase()] == home_level)) || ((team.toUpperCase() == away_team) && (LEVELS[level.toUpperCase()] == away_level)) || ((team.toUpperCase().indexOf('NATIONAL.') == 0) && (home_level == LEVELS['MLB'])) || ((team.toUpperCase().startsWith('FREE.') && cache_data.dates[0].games[j].broadcasts && cache_data.dates[0].games[j].broadcasts[0] && (cache_data.dates[0].games[j].broadcasts[0].freeGame == true))) ) {
1801
1811
 
1802
1812
  // Check if Winter League / MiLB game first
1803
- if ( (cache_data.dates[0].games[j].teams['home'].team.sport.id != LEVELS['MLB']) && (mediaType == 'MLBTV') ) {
1813
+ if ( (home_level != LEVELS['MLB']) && (mediaType == 'MLBTV') ) {
1804
1814
  this.debuglog('matched non-MLB team for ' + cache_data.dates[0].games[j].teams['home'].team.abbreviation + '@' + cache_data.dates[0].games[j].teams['away'].team.abbreviation)
1805
1815
  if ( cache_data.dates[0].games[j].broadcasts ) {
1806
1816
  let broadcastName = 'N/A'
@@ -2231,6 +2241,9 @@ class sessionClass {
2231
2241
  team_ids += ',' + AFFILIATE_TEAM_IDS[includeTeams[i]]
2232
2242
  }
2233
2243
  }
2244
+ if ( includeTeams.includes('LIDOM') ) {
2245
+ team_ids += this.getLidomTeamIds()
2246
+ }
2234
2247
  } else {
2235
2248
  team_ids = this.getTeamIds()
2236
2249
  for (let i=0; i<this.credentials.fav_teams.length; i++) {
@@ -2238,6 +2251,9 @@ class sessionClass {
2238
2251
  team_ids += ',' + AFFILIATE_TEAM_IDS[this.credentials.fav_teams[i]]
2239
2252
  }
2240
2253
  }
2254
+ if ( (excludeTeams.length == 0) || !excludeTeams.includes('LIDOM') ) {
2255
+ team_ids += this.getLidomTeamIds()
2256
+ }
2241
2257
  }
2242
2258
  }
2243
2259
 
@@ -2265,19 +2281,21 @@ class sessionClass {
2265
2281
  this.debuglog('getTVData processing game ' + j + ' for date ' + cache_data.dates[i].date)
2266
2282
  // Check if non-MLB (Winter League / MiLB) game first
2267
2283
  if ( (cache_data.dates[i].games[j].teams['home'].team.sport.id != LEVELS['MLB']) && (cache_data.dates[i].games[j].teams['away'].team.sport.id != LEVELS['MLB']) && (mediaType == 'MLBTV') ) {
2284
+ let league_id = cache_data.dates[i].games[j].teams['home'].team.league.id
2285
+ let broadcastName = 'N/A'
2268
2286
  if ( cache_data.dates[i].games[j].broadcasts ) {
2269
- let broadcastName = 'N/A'
2270
2287
  for (var k = 0; k < cache_data.dates[i].games[j].broadcasts.length; k++) {
2271
2288
  if ( cache_data.dates[i].games[j].broadcasts[k].name != 'Audio' ) {
2272
2289
  broadcastName = mediaType
2273
2290
  break
2274
2291
  }
2275
2292
  }
2276
- if ( broadcastName == 'N/A' ) {
2293
+ }
2294
+ if ( (broadcastName == 'N/A') && (league_id != LIDOM_ID) ) {
2277
2295
  continue
2278
2296
  } else {
2279
- for (var k = 0; k < cache_data.dates[i].games[j].broadcasts.length; k++) {
2280
- let league_id = cache_data.dates[i].games[j].teams['home'].team.league.id
2297
+ //for (var k = 0; k < cache_data.dates[i].games[j].broadcasts.length; k++) {
2298
+ if (broadcastName == 'N/A') broadcastName = 'MLBTV'
2281
2299
  let team = cache_data.dates[i].games[j].teams['home'].team.abbreviation
2282
2300
  let team_id = cache_data.dates[i].games[j].teams['home'].team.id.toString()
2283
2301
  let opponent_team_id = cache_data.dates[i].games[j].teams['away'].team.id.toString()
@@ -2386,10 +2404,9 @@ class sessionClass {
2386
2404
  // MILB guide XML
2387
2405
  programs += await this.generate_xml_program(channelid, start, stop, title, description, logo, this.convertDateToAirDate(gameDate), subtitle, team_id, cache_data.dates[i].games[j].gamePk, away_team, home_team)
2388
2406
 
2389
- break
2390
- }
2407
+ //break
2408
+ //}
2391
2409
  }
2392
- }
2393
2410
  } else {
2394
2411
  // Begin MLB games
2395
2412
  // check blackout status, if necessary