avirate.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import sys
  2. import struct
  3. from fractions import Fraction
  4. def pp4(fourcc):
  5. (a,b,c,d) = struct.unpack("4B", fourcc)
  6. return "%02x%02x%02x%02x" % (d, c, b, a)
  7. class Avi:
  8. def __init__(self, filename):
  9. self.f = open(filename, "r+b")
  10. self.atime = 0
  11. self.vtime = 0
  12. def get(self, n):
  13. return self.f.read(n)
  14. def unpack(self, fmt):
  15. sz = struct.calcsize(fmt)
  16. return struct.unpack(fmt, self.get(sz))
  17. def parse(self, level = 0):
  18. fourcc = self.get(4)
  19. (size, ) = self.unpack("I")
  20. if fourcc in ('RIFF', 'LIST'):
  21. print (" " * level)+ fourcc, pp4(fourcc), size
  22. if fourcc == 'RIFF':
  23. self.remainder = size - 4
  24. else:
  25. self.remainder -= 12
  26. _ = self.get(4)
  27. sz = size - 4
  28. while sz:
  29. sz -= self.parse(level + 1)
  30. assert 0 <= sz
  31. else:
  32. if fourcc == 'avih':
  33. (
  34. _,_,_,
  35. dwFlags,dwTotalFrames,_,dwStreams,_,
  36. dwWidth,dwHeight,
  37. _,_,_,_
  38. ) = self.unpack("IIIIIIIIIIIIII")
  39. print (" " * level)+'flags', '%04x' % dwFlags, dwTotalFrames,dwStreams,dwWidth,dwHeight
  40. elif fourcc == 'strh':
  41. o = self.f.tell()
  42. (
  43. fccType, fccHandler,
  44. dwFlags, wPriority,
  45. wLanguage, dwInitialFrames,
  46. dwScale, dwRate,
  47. dwStart, dwLength,
  48. dwSuggestedBufferSize,
  49. dwQuality,
  50. dwSampleSize,
  51. _,_,_,_) = self.unpack("4s4sIHHIIIIIIII4H")
  52. if fccType == 'vids':
  53. print 'offset', o
  54. self.rate_offset = o + 20
  55. print (
  56. fccType, fccHandler,
  57. dwFlags,
  58. wPriority, wLanguage,
  59. dwInitialFrames,
  60. dwScale, dwRate,
  61. dwStart, dwLength,
  62. dwSuggestedBufferSize,
  63. dwQuality,
  64. dwSampleSize)
  65. print float(dwRate) / dwScale, 'samples/s'
  66. elif fourcc == 'strf':
  67. d = self.get(size)
  68. if 0:
  69. if size == 16:
  70. print struct.unpack("HHIIHH", d)
  71. if size == 18:
  72. print struct.unpack("HHIIHHH", d)
  73. elif fourcc == '01dc':
  74. d = self.get(size)
  75. if d:
  76. self.vtime += 1 / 30.
  77. elif fourcc == '01wb':
  78. self.samples.write(self.get(size)[4:])
  79. self.atime += (size - 0) / 44100.
  80. else:
  81. self.get(size)
  82. # "A=%7.3f V=%7.3f %7.3f" % (self.atime, self.vtime, self.atime - self.vtime)
  83. # print (" " * level) + 'chunk', fourcc, pp4(fourcc), size, "%08x" % (self.remainder)
  84. self.remainder -= ((9 + size) & -2)
  85. if size & 1:
  86. self.get(1)
  87. # return 8 + ((size + 1) & -2)
  88. return (9 + size) & -2
  89. if __name__ == '__main__':
  90. rate = Fraction(sys.argv[1])
  91. print repr(rate)
  92. a = Avi(sys.argv[2])
  93. a.parse()
  94. a.f.seek(a.rate_offset)
  95. a.f.write(struct.pack("II", rate.denominator, rate.numerator))