Guest User

Untitled

a guest
May 28th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.32 KB | None | 0 0
  1. package util
  2.  
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "math"
  7. "os"
  8. "strings"
  9. "time"
  10. )
  11.  
  12. func Dump(filepath string) {
  13. file, _ := os.Open(filepath)
  14. defer file.Close()
  15.  
  16. mp4Box := NewEmptyBox("mp4", 0, math.MaxInt64, file)
  17. mp4Box.readChildBoxes()
  18. fmt.Print(mp4Box)
  19. }
  20.  
  21. func (b *BoxReader) readChildBoxes() {
  22. child := b.readChildBox()
  23. for child != nil {
  24. switch child.name {
  25. case "ftyp":
  26. child.readFileTypeBox()
  27. case "moov":
  28. child.readChildBoxes()
  29. case "trak":
  30. child.readChildBoxes()
  31. case "mvhd":
  32. child.readMovieHeaderBox()
  33. case "tkhd":
  34. child.readTrackHeaderBox()
  35. case "mdia":
  36. child.readChildBoxes()
  37. case "mdhd":
  38. child.readMediaHeaderBox()
  39. case "hdlr":
  40. child.readHandlerReferenceBox()
  41. case "minf":
  42. child.readChildBoxes()
  43. case "stbl":
  44. child.readChildBoxes()
  45. case "stsd":
  46. child.readSampleDescriptionBox()
  47. case "stsz":
  48. child.readSampleSizeBox()
  49. case "stts":
  50. child.readSampleTableBox()
  51. case "udta":
  52. child.readChildBoxes()
  53. case "dinf":
  54. child.readChildBoxes()
  55. case "dref":
  56. child.readDataReferenceBox()
  57. case "meta":
  58. child.readMetaBox()
  59. }
  60.  
  61. child = b.readChildBox()
  62. }
  63. }
  64.  
  65. var byteCount int64
  66.  
  67. type BoxReader struct {
  68. name string
  69. start int64
  70. length int64
  71. bytes []byte
  72. pos int64
  73. data map[string]interface{}
  74. version int64
  75. parent *BoxReader
  76. children []*BoxReader
  77. file *os.File
  78. }
  79.  
  80. func NewEmptyBox(name string, start, length int64, file *os.File) *BoxReader {
  81. byteCount = 8
  82. return &BoxReader{
  83. name: name,
  84. start: start,
  85. length: length,
  86. children: []*BoxReader{},
  87. data: map[string]interface{}{},
  88. file: file,
  89. }
  90. }
  91.  
  92. func (b *BoxReader) readChildBox() *BoxReader {
  93. var child *BoxReader
  94. if b.pos < (b.start + b.length) {
  95. buffer := make([]byte, 8)
  96. _, err := b.file.ReadAt(buffer, b.pos)
  97. if err == nil {
  98. child = NewEmptyBox(string(buffer[4:]), b.pos, convertBytesToInt(buffer[0:4]), b.file)
  99. child.parent = b
  100. child.pos = b.pos + 8
  101.  
  102. b.children = append(b.children, child)
  103. b.pos += child.length
  104. }
  105. }
  106. return child
  107. }
  108.  
  109. func (b *BoxReader) readSampleEntryBox() *BoxReader {
  110. length := b.readInt("length", 4)
  111. name := b.readString("name", 4)
  112. parentPos := b.pos - 8
  113. bytes := b.bytes[parentPos : parentPos+length]
  114.  
  115. sampleEntry := &BoxReader{
  116. name: name,
  117. start: b.start + parentPos,
  118. pos: 8,
  119. length: length,
  120. bytes: bytes,
  121. parent: b,
  122. children: []*BoxReader{},
  123. data: map[string]interface{}{},
  124. }
  125.  
  126. b.pos += length
  127. b.children = append(b.children, sampleEntry)
  128.  
  129. return sampleEntry
  130. }
  131.  
  132. func (b *BoxReader) readBytes() {
  133. if b.bytes == nil {
  134. b.bytes = make([]byte, b.length)
  135. b.file.ReadAt(b.bytes, b.start)
  136. b.pos = 8
  137. }
  138. }
  139.  
  140. func (b *BoxReader) readFullBox() {
  141. b.version = b.readInt("version", 1)
  142. b.readInt("flags", 3)
  143. }
  144.  
  145. func (b *BoxReader) ReadFullDateBox() {
  146. b.readFullBox()
  147. if b.version == 0 {
  148. b.readDate("created", 4)
  149. b.readDate("modified", 4)
  150. } else {
  151. b.readDate("created", 8)
  152. b.readDate("modified", 8)
  153. }
  154. }
  155.  
  156. func (b *BoxReader) readFileTypeBox() {
  157. b.readBytes()
  158. b.readString("majorBrand", 4)
  159. b.readInt("minorVersion", 4)
  160. b.readString("compatibleBrands", b.length-b.pos)
  161. }
  162.  
  163. // mvhd
  164. func (b *BoxReader) readMovieHeaderBox() {
  165. b.readBytes()
  166. b.ReadFullDateBox()
  167. b.readInt("timeScale", 4)
  168. b.readInt("duration", 4)
  169. b.readInt("preferredRate", 4)
  170. b.readInt("preferredVolume", 2)
  171. b.readNil("reserved", 10)
  172. b.readNil("matrix", 36)
  173. b.readInt("previewTime", 4)
  174. b.readInt("previewDuration", 4)
  175. b.readInt("posterTime", 4)
  176. b.readInt("selectionTime", 4)
  177. b.readInt("selectionDuration", 4)
  178. b.readInt("currentTime", 4)
  179. b.readInt("nextTrackID", 4)
  180.  
  181. duration := (time.Second * time.Duration(b.data["duration"].(int64)/b.data["timeScale"].(int64)))
  182. b.data["durationSec"] = duration.Seconds()
  183. }
  184.  
  185. // trak
  186. func (b *BoxReader) readTrackHeaderBox() {
  187. b.readBytes()
  188. b.ReadFullDateBox()
  189. if b.version == 0 {
  190. b.readInt("tid", 4)
  191. b.readNil("reserved1", 4)
  192. b.readInt("duration", 4)
  193. } else {
  194. b.readInt("tid", 4)
  195. b.readNil("reserved1", 4)
  196. b.readInt("duration", 8)
  197. }
  198.  
  199. b.readNil("reserved2", 8)
  200. b.readInt("layer", 2)
  201. b.readInt("altGroup", 2)
  202. b.readInt("volume", 2)
  203. b.readNil("reserved3", 2) // If you don't read this then the width and height are correct
  204. b.readNil("matrix", 36)
  205. b.readInt("width", 4)
  206. b.readInt("height", 4)
  207. }
  208.  
  209. // mdhd
  210. func (b *BoxReader) readMediaHeaderBox() {
  211. b.readBytes()
  212. b.ReadFullDateBox()
  213. if b.version == 0 {
  214. b.readInt("timeScale", 4)
  215. b.readInt("duration", 4)
  216. } else {
  217. b.readInt("timeScale", 4)
  218. b.readInt("duration", 8)
  219. }
  220. b.readNil("language", 2)
  221. b.readNil("preDefined", 2)
  222.  
  223. }
  224.  
  225. // hdlr
  226. func (b *BoxReader) readHandlerReferenceBox() {
  227. b.readBytes()
  228. b.readFullBox()
  229. b.readNil("predefined", 4)
  230. b.readString("handlerType", 4)
  231. b.readNil("reserved", 12)
  232. b.ReadTerminatedString("name")
  233.  
  234. b.parent.parent.data["handlerType"] = b.data["handlerType"]
  235. }
  236.  
  237. // stsd
  238. func (b *BoxReader) readSampleDescriptionBox() {
  239. b.readBytes()
  240. b.readFullBox()
  241. entryCount := int(b.readInt("entryCount", 4))
  242. for i := 0; i < entryCount; i++ {
  243. entryBox := b.readSampleEntryBox()
  244. switch b.parent.parent.parent.parent.data["handlerType"] {
  245. case "soun":
  246. entryBox.readNil("reserved1", 8)
  247. entryBox.readInt("channelcount", 2)
  248. entryBox.readInt("sampleSize", 2)
  249. entryBox.readNil("predefined1", 2)
  250. entryBox.readNil("reserved2", 2)
  251. entryBox.readInt("sampleRate", 4) // timescale of media << 16
  252. case "vide":
  253. entryBox.readNil("reserved", 6)
  254. entryBox.readInt("dataRefIndex", 2)
  255. entryBox.readNil("predefined1", 2)
  256. entryBox.readNil("reserved1", 2)
  257. entryBox.readNil("predefined2", 12)
  258. entryBox.readInt("width", 2)
  259. entryBox.readInt("height", 2)
  260. entryBox.readInt("hrez", 4)
  261. entryBox.readInt("vrez", 4)
  262. entryBox.readInt("reserved2", 4)
  263. entryBox.readInt("frameCount", 2)
  264. entryBox.readString("compressorName", 4)
  265. entryBox.readInt("depth", 2)
  266. entryBox.readInt("predefined3", 2)
  267. case "hint":
  268. }
  269. }
  270. }
  271.  
  272. // stsz
  273. func (b *BoxReader) readSampleSizeBox() {
  274. b.readBytes()
  275. b.readFullBox()
  276. b.readInt("sampleSize", 4)
  277. b.readInt("sampleCount", 4)
  278. }
  279.  
  280. // stts
  281. func (b *BoxReader) readSampleTableBox() {
  282. b.readBytes()
  283. b.readFullBox()
  284. b.readInt("entryCount", 4)
  285. }
  286.  
  287. // dref - Nothing of interest here.
  288. func (b *BoxReader) readDataReferenceBox() {
  289. }
  290.  
  291. // meta
  292. func (b *BoxReader) readMetaBox() {
  293. b.readBytes()
  294. b.readFullBox()
  295.  
  296. for b.pos < b.length {
  297. child := NewEmptyBox(string(b.bytes[b.pos+4:b.pos+8]), b.pos, convertBytesToInt(b.bytes[b.pos:b.pos+4]), b.file)
  298. child.parent = b
  299. child.pos = b.pos + 8
  300.  
  301. b.children = append(b.children, child)
  302. b.pos += child.length
  303. }
  304. }
  305.  
  306. func (b *BoxReader) String() string {
  307. var buf strings.Builder
  308. b.Write(0, &buf)
  309. return buf.String()
  310. }
  311.  
  312. func (b *BoxReader) Write(depth int, buf *strings.Builder) {
  313. WriteIndent(depth, buf)
  314. buf.WriteString(fmt.Sprintf("%v [%v]\n", b.name, b.length))
  315. if len(b.data) > 0 {
  316. j, err := json.Marshal(b.data)
  317. if err == nil {
  318. WriteIndent(depth+1, buf)
  319. buf.WriteString(string(j))
  320. buf.WriteRune('\n')
  321. }
  322. }
  323. for _, child := range b.children {
  324. child.Write(depth+1, buf)
  325. }
  326. }
  327.  
  328. func WriteIndent(indent int, buf *strings.Builder) {
  329. for x := 0; x < indent; x++ {
  330. buf.WriteString(" ")
  331. }
  332. }
  333.  
  334. func (b *BoxReader) GetBytes(name string, length int64) []byte {
  335. oldPos := b.pos
  336. b.pos = oldPos + length
  337.  
  338. result := b.bytes[oldPos:b.pos]
  339. byteCount += length
  340. return result
  341. }
  342.  
  343. func (b *BoxReader) readNil(name string, length int64) {
  344. b.GetBytes(name, length)
  345. }
  346.  
  347. func (b *BoxReader) readDate(name string, length int64) int64 {
  348. value := convertBytesToInt(b.GetBytes(name, length))
  349. value = value - 2082844800
  350. b.data[name] = time.Unix(value, 0).UTC().Format(time.RFC3339)
  351. return value
  352. }
  353.  
  354. func (b *BoxReader) readInt(name string, length int64) int64 {
  355. value := convertBytesToInt(b.GetBytes(name, length))
  356. b.data[name] = value
  357. return value
  358. }
  359.  
  360. func (b *BoxReader) readString(name string, length int64) string {
  361. value := string(b.GetBytes(name, length))
  362. b.data[name] = value
  363. return value
  364. }
  365.  
  366. func (b *BoxReader) ReadTerminatedString(name string) string {
  367. var buf strings.Builder
  368. for b.bytes[b.pos] != 0 && b.bytes[b.pos+1] != 0 {
  369. buf.WriteByte(b.bytes[b.pos])
  370. buf.WriteByte(b.bytes[b.pos+1])
  371. b.pos += 2
  372. }
  373. value := buf.String()
  374. b.data[name] = value
  375. return value
  376. }
  377.  
  378. func convertBytesToInt(buf []byte) int64 {
  379. res := 0
  380. for i := len(buf) - 1; i >= 0; i-- {
  381. b := int(buf[i])
  382. shift := uint((len(buf) - 1 - i) * 8)
  383. res += b << shift
  384. }
  385. return int64(res)
  386. }
Add Comment
Please, Sign In to add comment