A Python UPnP Media Server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
2.3 KiB

  1. #!/usr/bin/env python
  2. import sys
  3. sys.path.append('/Users/jgurney/p4/bktrau/info')
  4. import itertools
  5. import mpegts
  6. import sys
  7. import sets
  8. def usage():
  9. print >>sys.stderr, 'Usage: %s <file> <pmtpid> <pid> ...' % sys.argv[0]
  10. sys.exit(1)
  11. def genpats(pmt):
  12. BASEPAT = map(None, "G@\x00\x10\x00\x00\xb0\r\x00\x00\xc1\x00\x00\x00\x01\xe0\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff")
  13. patidx = 4 + 1 # TS header + pointer table
  14. BASEPAT[patidx + 10] = chr(0xe0 | ((pmt >> 8) & 0x1f))
  15. BASEPAT[patidx + 11] = chr(pmt & 0xff)
  16. newcrc = mpegts.psip_calc_crc32(''.join(BASEPAT[patidx:patidx + 12]))
  17. newcrc = map(lambda x, crc = newcrc: chr((crc >> (8 * (3 - x))) & 0xff), range(4))
  18. BASEPAT[patidx + 12:patidx + 16] = newcrc
  19. assert len(BASEPAT) == mpegts.TSPKTLEN
  20. ret = []
  21. old = ord(BASEPAT[3]) & 0xf0
  22. for i in range(16): # continuity
  23. BASEPAT[3] = chr(old | i)
  24. ret.append(''.join(BASEPAT))
  25. return ret
  26. def producets(inp, pmtpid, *pids):
  27. print `inp`, `pmtpid`, `pids`
  28. pats = itertools.cycle(genpats(pmtpid))
  29. # XXX - check if all pids are ints? in range?
  30. pids = sets.Set(pids)
  31. stream = mpegts.TSPStream(inp)
  32. for i in stream:
  33. frst = ord(i[1])
  34. # Get first and error bits for testing.
  35. pid = (frst & 0x1f) << 8 | ord(i[2])
  36. if pid == pmtpid and (frst & 0xc0) == 0x40:
  37. yield pats.next()
  38. # XXX - we probably want to rewrite the PMT to only
  39. # include the pids we are sending.
  40. yield i
  41. elif pid in pids:
  42. yield i
  43. def main():
  44. if len(sys.argv) < 3:
  45. usage()
  46. pmtpid = int(sys.argv[2])
  47. pids = map(int, sys.argv[3:])
  48. inp = open(sys.argv[1])
  49. out = sys.stdout
  50. producer = producets(inp, pmtpid, *pids)
  51. filter(lambda x: out.write(x), producer)
  52. if __name__ == '__main__':
  53. main()