1
1
mirror of https://github.com/wader/fq.git synced 2024-12-23 21:31:33 +03:00

Merge pull request #606 from wader/id3v2-fix-ctoc-header

id3v2: Decode subframes for CTOC and add struct for headers
This commit is contained in:
Mattias Wadman 2023-03-05 19:38:08 +01:00 committed by GitHub
commit a1020c5f19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1666 additions and 1759 deletions

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -14,8 +14,8 @@ s() {
c "Overview of mp3 file"
s "fq . file.mp3"
echo
c "Show ID3v2 tag inside mp3 file"
s "fq '.headers[0]' file.mp3"
c "Show header of first ID3v2 tag inside mp3 file"
s "fq '.headers[0].header' file.mp3"
echo
c "Show encoder software used"
s "fq -r '.frames[0].tag.encoder | tovalue' file.mp3"

View File

@ -433,6 +433,7 @@ func decodeFrame(d *decode.D, version int) uint64 {
d.FieldStrFn("entry", textNullFn(encodingUTF8))
}
})
decodeFrames(d, version, uint64(d.BitsLeft()/8))
},
// id3v2.0
@ -607,23 +608,23 @@ func decodeFrames(d *decode.D, version int, size uint64) {
}
func id3v2Decode(d *decode.D) any {
d.AssertAtLeastBitsLeft(4 * 8)
d.FieldUTF8("magic", 3, d.StrAssert("ID3"))
version := int(d.FieldU8("version"))
versionValid := version == 2 || version == 3 || version == 4
if !versionValid {
d.Fatalf("unsupported version %d", version)
}
d.FieldU8("revision")
var version uint64
var extendedHeader bool
d.FieldStruct("flags", func(d *decode.D) {
d.FieldBool("unsynchronisation")
extendedHeader = d.FieldBool("extended_header")
d.FieldBool("experimental_indicator")
d.FieldU5("unused")
var size uint64
d.AssertAtLeastBitsLeft(4 * 8)
d.FieldStruct("header", func(d *decode.D) {
d.FieldUTF8("magic", 3, d.StrAssert("ID3"))
version = d.FieldU8("version", d.UintAssert(2, 3, 4))
d.FieldU8("revision")
d.FieldStruct("flags", func(d *decode.D) {
d.FieldBool("unsynchronisation")
extendedHeader = d.FieldBool("extended_header")
d.FieldBool("experimental_indicator")
d.FieldU5("unused")
})
size = d.FieldUintFn("size", decodeSyncSafeU32)
})
size := d.FieldUintFn("size", decodeSyncSafeU32)
var extHeaderSize uint64
if extendedHeader {
@ -640,7 +641,7 @@ func id3v2Decode(d *decode.D) any {
})
}
decodeFrames(d, version, size)
decodeFrames(d, int(version), size)
return nil
}

View File

@ -2,15 +2,16 @@
# fq test.mp3 '.. | select(format == "id3v2")._bytes' > apic
$ fq -d id3v2 dv apic
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: apic (id3v2) 0x0-0xb3.7 (180)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 04 | . | version: 4 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 01 2a | ...* | size: 170 0x6-0x9.7 (4)
| | | header{}: 0x0-0x9.7 (10)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 04 | . | version: 4 (valid) 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 01 2a | ...* | size: 170 0x6-0x9.7 (4)
| | | frames[0:2]: 0xa-0xa9.7 (160)
| | | [0]{}: frame 0xa-0x22.7 (25)
0x00| 54 53 53 45 | TSSE | id: "TSSE" (Software/Hardware and settings used for encoding) 0xa-0xd.7 (4)

BIN
format/id3/testdata/ctoc vendored Normal file

Binary file not shown.

71
format/id3/testdata/ctoc.fqtest vendored Normal file
View File

@ -0,0 +1,71 @@
$ fq -d id3v2 dv ctoc
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: ctoc (id3v2) 0x0-0x9e.7 (159)
| | | header{}: 0x0-0x9.7 (10)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 03 | . | version: 3 (valid) 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 01 95 | .... | size: 149 0x6-0x9.7 (4)
| | | frames[0:1]: 0xa-0x9e.7 (149)
| | | [0]{}: frame 0xa-0x9e.7 (149)
0x00| 43 54 4f 43 | CTOC | id: "CTOC" (Table of contents) 0xa-0xd.7 (4)
0x00| 00 00| ..| size: 139 0xe-0x11.7 (4)
0x10|00 8b |.. |
| | | flags{}: 0x12-0x13.7 (2)
0x10| 00 | . | tag_alter_preservation: false 0x12-0x12 (0.1)
0x10| 00 | . | file_alter_preservation: false 0x12.1-0x12.1 (0.1)
0x10| 00 | . | read_only: false 0x12.2-0x12.2 (0.1)
0x10| 00 | . | unused0: 0 0x12.3-0x12.7 (0.5)
0x10| 00 | . | compression: false 0x13-0x13 (0.1)
0x10| 00 | . | encryption: false 0x13.1-0x13.1 (0.1)
0x10| 00 | . | grouping_identity: false 0x13.2-0x13.2 (0.1)
0x10| 00 | . | unused1: 0 0x13.3-0x13.7 (0.5)
0x10| 54 4f 43 4d 00 | TOCM. | element_id: "TOCM" 0x14-0x18.7 (5)
0x10| 03 | . | ctoc_flags: 3 0x19-0x19.7 (1)
0x10| 13 | . | entry_count: 19 0x1a-0x1a.7 (1)
| | | entries[0:19]: 0x1b-0x6f.7 (85)
0x10| 63 68 30 00 | ch0. | [0]: "ch0" entry 0x1b-0x1e.7 (4)
0x10| 63| c| [1]: "ch1" entry 0x1f-0x22.7 (4)
0x20|68 31 00 |h1. |
0x20| 63 68 32 00 | ch2. | [2]: "ch2" entry 0x23-0x26.7 (4)
0x20| 63 68 33 00 | ch3. | [3]: "ch3" entry 0x27-0x2a.7 (4)
0x20| 63 68 34 00 | ch4. | [4]: "ch4" entry 0x2b-0x2e.7 (4)
0x20| 63| c| [5]: "ch5" entry 0x2f-0x32.7 (4)
0x30|68 35 00 |h5. |
0x30| 63 68 36 00 | ch6. | [6]: "ch6" entry 0x33-0x36.7 (4)
0x30| 63 68 37 00 | ch7. | [7]: "ch7" entry 0x37-0x3a.7 (4)
0x30| 63 68 38 00 | ch8. | [8]: "ch8" entry 0x3b-0x3e.7 (4)
0x30| 63| c| [9]: "ch9" entry 0x3f-0x42.7 (4)
0x40|68 39 00 |h9. |
0x40| 63 68 31 30 00 | ch10. | [10]: "ch10" entry 0x43-0x47.7 (5)
0x40| 63 68 31 31 00 | ch11. | [11]: "ch11" entry 0x48-0x4c.7 (5)
0x40| 63 68 31| ch1| [12]: "ch12" entry 0x4d-0x51.7 (5)
0x50|32 00 |2. |
0x50| 63 68 31 33 00 | ch13. | [13]: "ch13" entry 0x52-0x56.7 (5)
0x50| 63 68 31 34 00 | ch14. | [14]: "ch14" entry 0x57-0x5b.7 (5)
0x50| 63 68 31 35| ch15| [15]: "ch15" entry 0x5c-0x60.7 (5)
0x60|00 |. |
0x60| 63 68 31 36 00 | ch16. | [16]: "ch16" entry 0x61-0x65.7 (5)
0x60| 63 68 31 37 00 | ch17. | [17]: "ch17" entry 0x66-0x6a.7 (5)
0x60| 63 68 31 38 00| ch18.| [18]: "ch18" entry 0x6b-0x6f.7 (5)
| | | frames[0:1]: 0x70-0x9e.7 (47)
| | | [0]{}: frame 0x70-0x9e.7 (47)
0x70|54 49 54 32 |TIT2 | id: "TIT2" (Title/songname/content description) 0x70-0x73.7 (4)
0x70| 00 00 00 25 | ...% | size: 37 0x74-0x77.7 (4)
| | | flags{}: 0x78-0x79.7 (2)
0x70| 00 | . | tag_alter_preservation: false 0x78-0x78 (0.1)
0x70| 00 | . | file_alter_preservation: false 0x78.1-0x78.1 (0.1)
0x70| 00 | . | read_only: false 0x78.2-0x78.2 (0.1)
0x70| 00 | . | unused0: 0 0x78.3-0x78.7 (0.5)
0x70| 00 | . | compression: false 0x79-0x79 (0.1)
0x70| 00 | . | encryption: false 0x79.1-0x79.1 (0.1)
0x70| 00 | . | grouping_identity: false 0x79.2-0x79.2 (0.1)
0x70| 00 | . | unused1: 0 0x79.3-0x79.7 (0.5)
0x70| 01 | . | text_encoding: "utf16" (1) 0x7a-0x7a.7 (1)
0x70| ff fe 54 00 61| ..T.a| text: "Table of contents" 0x7b-0x9e.7 (36)
0x80|00 62 00 6c 00 65 00 20 00 6f 00 66 00 20 00 63|.b.l.e. .o.f. .c|
0x90|00 6f 00 6e 00 74 00 65 00 6e 00 74 00 73 00| |.o.n.t.e.n.t.s.||

View File

@ -1,15 +1,16 @@
# ffmpeg -f lavfi -i sine -t 0s -id3v2_version 3 -f mp3 pipe:1 > id3v23
$ fq -d id3v2 dv id3v23
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: id3v23 (id3v2) 0x0-0x2c.7 (45)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 03 | . | version: 3 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4)
| | | header{}: 0x0-0x9.7 (10)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 03 | . | version: 3 (valid) 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4)
| | | frames[0:1]: 0xa-0x22.7 (25)
| | | [0]{}: frame 0xa-0x22.7 (25)
0x00| 54 53 53 45 | TSSE | id: "TSSE" (Software/Hardware and settings used for encoding) 0xa-0xd.7 (4)

View File

@ -1,15 +1,16 @@
# ffmpeg -f lavfi -i sine -t 0s -id3v2_version 4 -f mp3 pipe:1 > id3v24
$ fq -d id3v2 dv id3v24
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: id3v24 (id3v2) 0x0-0x2c.7 (45)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 04 | . | version: 4 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4)
| | | header{}: 0x0-0x9.7 (10)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 04 | . | version: 4 (valid) 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4)
| | | frames[0:1]: 0xa-0x22.7 (25)
| | | [0]{}: frame 0xa-0x22.7 (25)
0x00| 54 53 53 45 | TSSE | id: "TSSE" (Software/Hardware and settings used for encoding) 0xa-0xd.7 (4)

View File

@ -1,14 +1,15 @@
$ fq -d id3v2 dv txxx-nonullterm
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: txxx-nonullterm (id3v2) 0x0-0x26.7 (39)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 03 | . | version: 3 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 00 1d | .... | size: 29 0x6-0x9.7 (4)
| | | header{}: 0x0-0x9.7 (10)
0x00|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x00| 03 | . | version: 3 (valid) 0x3-0x3.7 (1)
0x00| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x00| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x00| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x00| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x00| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x00| 00 00 00 1d | .... | size: 29 0x6-0x9.7 (4)
| | | frames[0:1]: 0xa-0x26.7 (29)
| | | [0]{}: frame 0xa-0x26.7 (29)
0x00| 54 58 58 58 | TXXX | id: "TXXX" (User defined text information frame) 0xa-0xd.7 (4)

View File

@ -4,15 +4,16 @@
# fq test.mp3 .headers[0]._bits > utf16-apic
$ fq -d id3v2 dv utf16-apic
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: utf16-apic (id3v2) 0x0-0x255.7 (598)
0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x000| 04 | . | version: 4 0x3-0x3.7 (1)
0x000| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x000| 00 00 04 4c | ...L | size: 588 0x6-0x9.7 (4)
| | | header{}: 0x0-0x9.7 (10)
0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x000| 04 | . | version: 4 (valid) 0x3-0x3.7 (1)
0x000| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x000| 00 00 04 4c | ...L | size: 588 0x6-0x9.7 (4)
| | | frames[0:2]: 0xa-0x155.7 (332)
| | | [0]{}: frame 0xa-0x12e.7 (293)
0x000| 41 50 49 43 | APIC | id: "APIC" (Attached picture) 0xa-0xd.7 (4)

View File

@ -3,15 +3,16 @@ $ fq -d mp3 dv header-zeros-frames.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: header-zeros-frames.mp3 (mp3) 0x0-0xff.7 (256)
| | | headers[0:1]: 0x0-0x2c.7 (45)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| [0]{}: header (id3v2) 0x0-0x2c.7 (45)
0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x000| 04 | . | version: 4 0x3-0x3.7 (1)
0x000| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x000| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4)
| | | header{}: 0x0-0x9.7 (10)
0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x000| 04 | . | version: 4 (valid) 0x3-0x3.7 (1)
0x000| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x000| 00 00 00 23 | ...# | size: 35 0x6-0x9.7 (4)
| | | frames[0:1]: 0xa-0x22.7 (25)
| | | [0]{}: frame 0xa-0x22.7 (25)
0x000| 54 53 53 45 | TSSE | id: "TSSE" (Software/Hardware and settings used for encoding) 0xa-0xd.7 (4)

View File

@ -3,15 +3,16 @@ $ fq -d mp3 dv headerfooter.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: headerfooter.mp3 (mp3) 0x0-0x25d.7 (606)
| | | headers[0:1]: 0x0-0x3c.7 (61)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| [0]{}: header (id3v2) 0x0-0x3c.7 (61)
0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x000| 04 | . | version: 4 0x3-0x3.7 (1)
0x000| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x000| 00 00 00 33 | ...3 | size: 51 0x6-0x9.7 (4)
| | | header{}: 0x0-0x9.7 (10)
0x000|49 44 33 |ID3 | magic: "ID3" (valid) 0x0-0x2.7 (3)
0x000| 04 | . | version: 4 (valid) 0x3-0x3.7 (1)
0x000| 00 | . | revision: 0 0x4-0x4.7 (1)
| | | flags{}: 0x5-0x5.7 (1)
0x000| 00 | . | unsynchronisation: false 0x5-0x5 (0.1)
0x000| 00 | . | extended_header: false 0x5.1-0x5.1 (0.1)
0x000| 00 | . | experimental_indicator: false 0x5.2-0x5.2 (0.1)
0x000| 00 | . | unused: 0 0x5.3-0x5.7 (0.5)
0x000| 00 00 00 33 | ...3 | size: 51 0x6-0x9.7 (4)
| | | frames[0:2]: 0xa-0x32.7 (41)
| | | [0]{}: frame 0xa-0x19.7 (16)
0x000| 54 49 54 32 | TIT2 | id: "TIT2" (Title/songname/content description) 0xa-0xd.7 (4)

View File

@ -72,16 +72,17 @@ $ fq -d mp4 dv dash_audio_init.mp4
0x0c0| 15 | . | pad: 0 0xcc-0xcc (0.1)
0x0c0| 15 c7 | .. | language: "eng" 0xcc.1-0xcd.7 (1.7)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| data{}: (id3v2) 0xce-0x11a.7 (77)
0x0c0| 49 44| ID| magic: "ID3" (valid) 0xce-0xd0.7 (3)
| | | header{}: 0xce-0xd7.7 (10)
0x0c0| 49 44| ID| magic: "ID3" (valid) 0xce-0xd0.7 (3)
0x0d0|33 |3 |
0x0d0| 04 | . | version: 4 0xd1-0xd1.7 (1)
0x0d0| 00 | . | revision: 0 0xd2-0xd2.7 (1)
| | | flags{}: 0xd3-0xd3.7 (1)
0x0d0| 00 | . | unsynchronisation: false 0xd3-0xd3 (0.1)
0x0d0| 00 | . | extended_header: false 0xd3.1-0xd3.1 (0.1)
0x0d0| 00 | . | experimental_indicator: false 0xd3.2-0xd3.2 (0.1)
0x0d0| 00 | . | unused: 0 0xd3.3-0xd3.7 (0.5)
0x0d0| 00 00 00 43 | ...C | size: 67 0xd4-0xd7.7 (4)
0x0d0| 04 | . | version: 4 (valid) 0xd1-0xd1.7 (1)
0x0d0| 00 | . | revision: 0 0xd2-0xd2.7 (1)
| | | flags{}: 0xd3-0xd3.7 (1)
0x0d0| 00 | . | unsynchronisation: false 0xd3-0xd3 (0.1)
0x0d0| 00 | . | extended_header: false 0xd3.1-0xd3.1 (0.1)
0x0d0| 00 | . | experimental_indicator: false 0xd3.2-0xd3.2 (0.1)
0x0d0| 00 | . | unused: 0 0xd3.3-0xd3.7 (0.5)
0x0d0| 00 00 00 43 | ...C | size: 67 0xd4-0xd7.7 (4)
| | | frames[0:1]: 0xd8-0x11a.7 (67)
| | | [0]{}: frame 0xd8-0x11a.7 (67)
0x0d0| 50 52 49 56 | PRIV | id: "PRIV" (Private frame) 0xd8-0xdb.7 (4)
@ -578,15 +579,16 @@ $ fq -d mp4 dv dash_video_init.mp4
0x00d0|15 |. | pad: 0 0xd0-0xd0 (0.1)
0x00d0|15 c7 |.. | language: "eng" 0xd0.1-0xd1.7 (1.7)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| data{}: (id3v2) 0xd2-0x11e.7 (77)
0x00d0| 49 44 33 | ID3 | magic: "ID3" (valid) 0xd2-0xd4.7 (3)
0x00d0| 04 | . | version: 4 0xd5-0xd5.7 (1)
0x00d0| 00 | . | revision: 0 0xd6-0xd6.7 (1)
| | | flags{}: 0xd7-0xd7.7 (1)
0x00d0| 00 | . | unsynchronisation: false 0xd7-0xd7 (0.1)
0x00d0| 00 | . | extended_header: false 0xd7.1-0xd7.1 (0.1)
0x00d0| 00 | . | experimental_indicator: false 0xd7.2-0xd7.2 (0.1)
0x00d0| 00 | . | unused: 0 0xd7.3-0xd7.7 (0.5)
0x00d0| 00 00 00 43 | ...C | size: 67 0xd8-0xdb.7 (4)
| | | header{}: 0xd2-0xdb.7 (10)
0x00d0| 49 44 33 | ID3 | magic: "ID3" (valid) 0xd2-0xd4.7 (3)
0x00d0| 04 | . | version: 4 (valid) 0xd5-0xd5.7 (1)
0x00d0| 00 | . | revision: 0 0xd6-0xd6.7 (1)
| | | flags{}: 0xd7-0xd7.7 (1)
0x00d0| 00 | . | unsynchronisation: false 0xd7-0xd7 (0.1)
0x00d0| 00 | . | extended_header: false 0xd7.1-0xd7.1 (0.1)
0x00d0| 00 | . | experimental_indicator: false 0xd7.2-0xd7.2 (0.1)
0x00d0| 00 | . | unused: 0 0xd7.3-0xd7.7 (0.5)
0x00d0| 00 00 00 43 | ...C | size: 67 0xd8-0xdb.7 (4)
| | | frames[0:1]: 0xdc-0x11e.7 (67)
| | | [0]{}: frame 0xdc-0x11e.7 (67)
0x00d0| 50 52 49 56| PRIV| id: "PRIV" (Private frame) 0xdc-0xdf.7 (4)

View File

@ -1,12 +1,12 @@
# ffmpeg -f lavfi -i sine -t 10ms test.mp3
$ fq -i . test.mp3
mp3> .headers[0].magic == "ID3"
mp3> .headers[0].header.magic == "ID3"
true
mp3> .headers[0].version == 4
mp3> .headers[0].header.version == 4
true
mp3> .frames[0].header.protection == true
false
mp3> .headers[0].flags + {}
mp3> .headers[0].header.flags + {}
{
"experimental_indicator": false,
"extended_header": false,
@ -17,11 +17,11 @@ mp3> ._gap
false
mp3> format
"mp3"
mp3> .headers[0].magic | format
mp3> .headers[0].header.magic | format
null
mp3> ._format
"mp3"
mp3> .headers[0].magic._format
mp3> .headers[0].header.magic._format
null
mp3> ^D
# TODO: use test format

View File

@ -1,13 +1,13 @@
$ fq -d mp3 '.headers[0].magic._bits[8:16] | hd' test.mp3
$ fq -d mp3 '.headers[0].header.magic._bits[8:16] | hd' test.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 44 | D |.: raw bits 0x1-0x1.7 (1)
$ fq -d mp3 '.headers[0].magic._bits | [.[8:16], .[0:8]] | hd' test.mp3
$ fq -d mp3 '.headers[0].header.magic._bits | [.[8:16], .[0:8]] | hd' test.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|44 49| |DI| |.: raw bits 0x0-0x1.7 (2)
$ fq -d mp3 '.headers[0].magic._bits | [.[8:16], .[0:8]] | tobits | hd' test.mp3
$ fq -d mp3 '.headers[0].header.magic._bits | [.[8:16], .[0:8]] | tobits | hd' test.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|44 49| |DI| |.: raw bits 0x0-0x1.7 (2)
$ fq -d mp3 '.headers[0].magic._bits | [.[8:16], .[0:8]] | tobytes | hd' test.mp3
$ fq -d mp3 '.headers[0].header.magic._bits | [.[8:16], .[0:8]] | tobytes | hd' test.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|44 49| |DI| |.: raw bits 0x0-0x1.7 (2)
$ fq -n '"12" | tobytes | hd'
@ -33,7 +33,7 @@ $ fq -d mp3 '.frames[]._bits[0:12] | tonumber' test.mp3
4095
4095
4095
$ fq -d mp3 '.headers[0].magic._bits[0:24] | tostring' test.mp3
$ fq -d mp3 '.headers[0].header.magic._bits[0:24] | tostring' test.mp3
"ID3"
$ fq -d mp3 '.frames[0].audio_data | ("", "md5", "base64", "snippet") as $f | tovalue({bits_format: $f})' test.mp3
"<5>AAAAAAA="
@ -47,7 +47,7 @@ mp3> [1, 2, 3] | tobytes
mp3> [1, 2, 3, [1, 2, 3]] | tobytes
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|01 02 03 01 02 03| |......| |.: raw bits 0x0-0x5.7 (6)
mp3> [1, 2, 3, [1, 2, 3], .headers[0].magic] | tobytes
mp3> [1, 2, 3, [1, 2, 3], .headers[0].header.magic] | tobytes
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|01 02 03 01 02 03 49 44 33| |......ID3| |.: raw bits 0x0-0x8.7 (9)
mp3> [-1] | tobytes

View File

@ -59,7 +59,7 @@ mp3> .[] = 1
"frames": 1,
"headers": 1
}
mp3> walk(tovalue) | .headers[0].magic
mp3> walk(tovalue) | .headers[0].header.magic
"ID3"
mp3> ^D
$ fq -d bytes 'png | d' test.mp3

View File

@ -1,7 +1,7 @@
/test.jq:
123
/test2.jq:
.headers[0].magic | tovalue
.headers[0].header.magic | tovalue
/err.jq:
asdad)
$ fq -n -f test.jq

View File

@ -24,11 +24,11 @@ $ fq -n '{a:1, b: 2} | tostream'
"b"
]
]
$ fq -d mp3 '{(.headers[0].magic): 123}' test.mp3
$ fq -d mp3 '{(.headers[0].header.magic): 123}' test.mp3
{
"ID3": 123
}
$ fq -d mp3 '{(.headers[0].magic): 123}' test.mp3
$ fq -d mp3 '{(.headers[0].header.magic): 123}' test.mp3
{
"ID3": 123
}
@ -257,12 +257,6 @@ $ fq -d mp3 '.frames[0] | to_entries[].key' test.mp3
# TODO: move this test as it depends on xml
$ fq -r '.headers[0] | to_xml({indent: 2})' test.mp3
<doc>
<flags>
<experimental_indicator>false</experimental_indicator>
<extended_header>false</extended_header>
<unsynchronisation>false</unsynchronisation>
<unused>0</unused>
</flags>
<frames>
<flags>
<compression>false</compression>
@ -282,11 +276,19 @@ $ fq -r '.headers[0] | to_xml({indent: 2})' test.mp3
<text>Lavf58.45.100</text>
<text_encoding>utf8</text_encoding>
</frames>
<magic>ID3</magic>
<header>
<flags>
<experimental_indicator>false</experimental_indicator>
<extended_header>false</extended_header>
<unsynchronisation>false</unsynchronisation>
<unused>0</unused>
</flags>
<magic>ID3</magic>
<revision>0</revision>
<size>35</size>
<version>4</version>
</header>
<padding><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></padding>
<revision>0</revision>
<size>35</size>
<version>4</version>
</doc>
$ fq -i
null> 0b0_1
@ -309,5 +311,5 @@ null> 0x012_3456789abcdefx
^ unexpected token "x"
null> ^D
# test JQValue in assign/update path
$ fq -c -d mp3 '.headers[0].version as $i | [] | .[$i] = 1 | .[$i] += 2' test.mp3
$ fq -c -d mp3 '.headers[0].header.version as $i | [] | .[$i] = 1 | .[$i] += 2' test.mp3
[null,null,null,null,3]

View File

@ -11,15 +11,15 @@ mp3> grep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x44
0x1d0|20 d4 29 52 98 c8 c8 f9 13 80 40 24 bc 91 23 42| .)R......@$..#B|
* |until 0x283.7 (end) (188) | |
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x40| 49 6e 66 6f | Info |.frames[0].tag.header: "Info" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
mp3> vgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x44])
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x20| 40| @|.frames[0].header.sample_rate: 44100 (0)
@ -28,31 +28,31 @@ mp3> vgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x4
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x1b0| 52 | R |.frames[2].header.sample_rate: 44100 (0)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x40| 49 6e 66 6f | Info |.frames[0].tag.header: "Info" (valid)
mp3> fgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x44])
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
mp3> bgrep(44100, "ID", "^ID3$", "^ID.?$", "Info", "magic", "\u00ff", [0x49, 0x44])
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x1c0| 11 4b 36 4a 08 83 58 c9| .K6J..X.|.frames[2].audio_data: raw bits
0x1d0|20 d4 29 52 98 c8 c8 f9 13 80 40 24 bc 91 23 42| .)R......@$..#B|
* |until 0x283.7 (end) (188) | |
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x40| 49 6e 66 6f | Info |.frames[0].tag.header: "Info" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
mp3> "64ff65ff66" | fromhex | bgrep("\u00ff"; "b")
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|64 ff 65 ff 66| |d.e.f| |.: raw bits 0x0-0x4.7 (5)
@ -65,11 +65,7 @@ mp3> grep_by(. == 44100)
0x1b0| 52 | R |.frames[2].header.sample_rate: 44100 (0)
mp3> grep_by(format == "id3v2")
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0]{}: header (id3v2)
0x00|49 44 33 |ID3 | magic: "ID3" (valid)
0x00| 04 | . | version: 4
0x00| 00 | . | revision: 0
0x00| 00 | . | flags{}:
0x00| 00 00 00 23 | ...# | size: 35
0x00|49 44 33 04 00 00 00 00 00 23 |ID3......# | header{}:
0x00| 54 53 53 45 00 00| TSSE..| frames[0:1]:
0x10|00 0f 00 00 03 4c 61 76 66 35 38 2e 34 35 2e 31|.....Lavf58.45.1|
0x20|30 30 00 |00. |

View File

@ -7,26 +7,20 @@ $ fq -d mp3 '.headers[].frames[0].size // 123' test.mp3
0x00| 00 00| ..|.headers[0].frames[0].size: 15
0x10|00 0f |.. |
# test each in decoded order
$ fq -d mp3 '.headers[0][]' test.mp3
$ fq -d mp3 '.headers[0].header[]' test.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 04 | . |.headers[0].version: 4
0x0| 04 | . |.headers[0].header.version: 4 (valid)
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.headers[0].revision: 0
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].flags{}:
0x0| 00 | . |.headers[0].header.revision: 0
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].header.flags{}:
0x0| 00 | . | unsynchronisation: false
0x0| 00 | . | extended_header: false
0x0| 00 | . | experimental_indicator: false
0x0| 00 | . | unused: 0
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 00 00 23 | ...# |.headers[0].size: 35
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].frames[0:1]:
0x00| 54 53 53 45 00 00| TSSE..| [0]{}: frame
0x10|00 0f 00 00 03 4c 61 76 66 35 38 2e 34 35 2e 31|.....Lavf58.45.1|
0x20|30 30 00 |00. |
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x20| 00 00 00 00 00 00 00 00 00 00 | .......... |.headers[0].padding: raw bits (all zero)
0x0| 00 00 00 23 | ...# |.headers[0].header.size: 35
# TODO: proper buffer_root test
$ fq -d mp3 -i . test.mp3
mp3> .frames[0].header.mpeg_version | (topath | path_to_expr), tovalue, toactual, tosym, todescription
@ -47,12 +41,13 @@ mp3> . | (root, buffer_root, format_root, parent | try (topath | path_to_expr) c
"."
"expected decode value but got: null (null)"
[]
mp3> .headers[0].magic | (root, buffer_root, format_root, parent | topath | path_to_expr), [parents | topath | path_to_expr]
mp3> .headers[0].header.magic | (root, buffer_root, format_root, parent | topath | path_to_expr), [parents | topath | path_to_expr]
"."
"."
".headers[0]"
".headers[0]"
".headers[0].header"
[
".headers[0].header",
".headers[0]",
".headers",
"."
@ -93,7 +88,7 @@ mp3> .headers as $c | (0, "abc") as $n | $n, try ($c | has($n)) catch .
true
"abc"
"cannot check whether array has a key: abc"
mp3> .headers[0].magic as $c | (0, "abc") as $n | $n, try ($c | has($n)) catch .
mp3> .headers[0].header.magic as $c | (0, "abc") as $n | $n, try ($c | has($n)) catch .
0
"has cannot be applied to: string"
"abc"
@ -168,7 +163,7 @@ true
true
"_abc"
"expected a extkey but got: _abc"
mp3> .headers[0].magic as $c | ("_start", "_stop", "_len", "_name", "_root", "_buffer_root", "_format_root", "_parent", "_sym", "_description", "_path", "_bits", "_bytes", "_error", "_gap", "_format", "_abc") as $n | $n, try ($c | has($n)) catch .
mp3> .headers[0].header.magic as $c | ("_start", "_stop", "_len", "_name", "_root", "_buffer_root", "_format_root", "_parent", "_sym", "_description", "_path", "_bits", "_bytes", "_error", "_gap", "_format", "_abc") as $n | $n, try ($c | has($n)) catch .
"_start"
true
"_stop"

View File

@ -6,12 +6,6 @@ mp3> .headers | ., tovalue, toactual, tosym, type, length?
* |until 0x2c.7 (45) | |
[
{
"flags": {
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
},
"frames": [
{
"flags": {
@ -33,11 +27,19 @@ mp3> .headers | ., tovalue, toactual, tosym, type, length?
"text_encoding": "utf8"
}
],
"magic": "ID3",
"padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"revision": 0,
"size": 35,
"version": 4
"header": {
"flags": {
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
},
"magic": "ID3",
"revision": 0,
"size": 35,
"version": 4
},
"padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
}
]
null
@ -46,17 +48,13 @@ null
1
mp3> .headers[0] | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0]{}: header (id3v2)
0x00|49 44 33 |ID3 | magic: "ID3" (valid)
0x00| 04 | . | version: 4
0x00| 00 | . | revision: 0
0x00| 00 | . | flags{}:
0x00| 00 00 00 23 | ...# | size: 35
0x00|49 44 33 04 00 00 00 00 00 23 |ID3......# | header{}:
0x00| 54 53 53 45 00 00| TSSE..| frames[0:1]:
0x10|00 0f 00 00 03 4c 61 76 66 35 38 2e 34 35 2e 31|.....Lavf58.45.1|
0x20|30 30 00 |00. |
0x20| 00 00 00 00 00 00 00 00 00 00 | .......... | padding: raw bits (all zero)
"object"
7
3
mp3> .headers[-1000] | ., type, length?
null
"null"
@ -76,12 +74,6 @@ mp3> .headers[0:-1] | ., type, length?
mp3> .headers[-1000:2000] | ., type, length?
[
{
"flags": {
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
},
"frames": [
{
"flags": {
@ -103,11 +95,19 @@ mp3> .headers[-1000:2000] | ., type, length?
"text_encoding": "utf8"
}
],
"magic": "ID3",
"padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"revision": 0,
"size": 35,
"version": 4
"header": {
"flags": {
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
},
"magic": "ID3",
"revision": 0,
"size": 35,
"version": 4
},
"padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
}
]
"array"
@ -130,11 +130,11 @@ mp3> .headers | type
mp3> .headers | tonumber
error: tonumber cannot be applied to: array
mp3> .headers | tostring
"[{\"flags\":{\"experimental_indicator\":false,\"extended_header\":false,\"unsynchronisation\":false,\"unused\":0},\"frames\":[{\"flags\":{\"compression\":false,\"data_length_indicator\":false,\"encryption\":false,\"file_alter_preservation\":false,\"grouping_identity\":false,\"read_only\":false,\"tag_alter_preservation\":false,\"unsync\":false,\"unused0\":0,\"unused1\":0,\"unused2\":0},\"id\":\"TSSE\",\"size\":15,\"text\":\"Lavf58.45.100\",\"text_encoding\":\"utf8\"}],\"magic\":\"ID3\",\"padding\":\"\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\",\"revision\":0,\"size\":35,\"version\":4}]"
"[{\"frames\":[{\"flags\":{\"compression\":false,\"data_length_indicator\":false,\"encryption\":false,\"file_alter_preservation\":false,\"grouping_identity\":false,\"read_only\":false,\"tag_alter_preservation\":false,\"unsync\":false,\"unused0\":0,\"unused1\":0,\"unused2\":0},\"id\":\"TSSE\",\"size\":15,\"text\":\"Lavf58.45.100\",\"text_encoding\":\"utf8\"}],\"header\":{\"flags\":{\"experimental_indicator\":false,\"extended_header\":false,\"unsynchronisation\":false,\"unused\":0},\"magic\":\"ID3\",\"revision\":0,\"size\":35,\"version\":4},\"padding\":\"\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\\u0000\"}]"
mp3> .headers + ""
error: cannot add: array ([{"flags":{"experimental_ ...]) and string ("")
error: cannot add: array ([{"frames":[{"flags":{"co ...]) and string ("")
mp3> .headers + 1
error: cannot add: array ([{"flags":{"experimental_ ...]) and number (1)
error: cannot add: array ([{"frames":[{"flags":{"co ...]) and number (1)
mp3> .headers._start | ., type, length?
0
"number"
@ -189,7 +189,7 @@ mp3> .headers._gap | ., type, length?
false
"boolean"
mp3> .headers.a = 1
error: expected an object but got: array ([{"flags":{"experimental_ ...])
error: expected an object but got: array ([{"frames":[{"flags":{"co ...])
mp3> .headers[0] = 1
{
"footers": [],
@ -853,13 +853,13 @@ mp3> .headers[0] |= empty
"headers": []
}
mp3> .headers | setpath(["a"]; 1)
error: expected an object but got: array ([{"flags":{"experimental_ ...])
error: expected an object but got: array ([{"frames":[{"flags":{"co ...])
mp3> .headers | setpath([0]; 1)
[
1
]
mp3> .headers | delpaths([["a"]])
error: expected an object but got: array ([{"flags":{"experimental_ ...])
error: expected an object but got: array ([{"frames":[{"flags":{"co ...])
mp3> .headers | delpaths([[0]])
[]
mp3> ^D

View File

@ -1,112 +1,113 @@
$ fq -i -d mp3 . test.mp3
mp3> .headers[0].flags.unsynchronisation | ., tovalue, toactual, tosym, type, length?
mp3> .headers[0].header.flags.unsynchronisation | ., tovalue, toactual, tosym, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.headers[0].flags.unsynchronisation: false
0x0| 00 | . |.headers[0].header.flags.unsynchronisation: false
false
false
null
"boolean"
mp3> .headers[0].flags.unsynchronisation[0] | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation[0] | ., type, length?
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation[-1000] | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation[-1000] | ., type, length?
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation[1000] | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation[1000] | ., type, length?
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation[1:3] | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation[1:3] | ., type, length?
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation[0:-1] | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation[0:-1] | ., type, length?
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation[-1000:2000] | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation[-1000:2000] | ., type, length?
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation["test"] | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation["test"] | ., type, length?
error: expected an object but got: boolean
mp3> [.headers[0].flags.unsynchronisation[]] | type, length?
mp3> [.headers[0].header.flags.unsynchronisation[]] | type, length?
error: cannot iterate over: boolean
mp3> .headers[0].flags.unsynchronisation | keys
mp3> .headers[0].header.flags.unsynchronisation | keys
error: keys cannot be applied to: boolean
mp3> .headers[0].flags.unsynchronisation | has("a")
mp3> .headers[0].header.flags.unsynchronisation | has("a")
error: has cannot be applied to: boolean
mp3> .headers[0].flags.unsynchronisation | has(0)
mp3> .headers[0].header.flags.unsynchronisation | has(0)
error: has cannot be applied to: boolean
mp3> .headers[0].flags.unsynchronisation | type
mp3> .headers[0].header.flags.unsynchronisation | type
"boolean"
mp3> .headers[0].flags.unsynchronisation | tonumber
mp3> .headers[0].header.flags.unsynchronisation | tonumber
error: tonumber cannot be applied to: boolean
mp3> .headers[0].flags.unsynchronisation | tostring
mp3> .headers[0].header.flags.unsynchronisation | tostring
"false"
mp3> .headers[0].flags.unsynchronisation + ""
mp3> .headers[0].header.flags.unsynchronisation + ""
error: cannot add: boolean (false) and string ("")
mp3> .headers[0].flags.unsynchronisation + 1
mp3> .headers[0].header.flags.unsynchronisation + 1
error: cannot add: boolean (false) and number (1)
mp3> .headers[0].flags.unsynchronisation._start | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._start | ., type, length?
40
"number"
40
mp3> .headers[0].flags.unsynchronisation._stop | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._stop | ., type, length?
41
"number"
41
mp3> .headers[0].flags.unsynchronisation._len | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._len | ., type, length?
1
"number"
1
mp3> .headers[0].flags.unsynchronisation._name | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._name | ., type, length?
"unsynchronisation"
"string"
17
mp3> .headers[0].flags.unsynchronisation._actual | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._actual | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.headers[0].flags.unsynchronisation: false
0x0| 00 | . |.headers[0].header.flags.unsynchronisation: false
"boolean"
mp3> .headers[0].flags.unsynchronisation._sym | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._sym | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.headers[0].flags.unsynchronisation: false
0x0| 00 | . |.headers[0].header.flags.unsynchronisation: false
"null"
0
mp3> .headers[0].flags.unsynchronisation._description | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._description | ., type, length?
null
"null"
0
mp3> .headers[0].flags.unsynchronisation._path | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._path | ., type, length?
[
"headers",
0,
"header",
"flags",
"unsynchronisation"
]
"array"
4
mp3> .headers[0].flags.unsynchronisation._bits | ., type, length?
5
mp3> .headers[0].header.flags.unsynchronisation._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.: raw bits 0x5-0x5 (0.1)
"string"
1
mp3> .headers[0].flags.unsynchronisation._bytes | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.: raw bits 0x5-0x5 (0.1)
"string"
0
mp3> .headers[0].flags.unsynchronisation._error | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._error | ., type, length?
null
"null"
0
mp3> .headers[0].flags.unsynchronisation._gap | ., type, length?
mp3> .headers[0].header.flags.unsynchronisation._gap | ., type, length?
false
"boolean"
mp3> .headers[0].flags.unsynchronisation.a = 1
mp3> .headers[0].header.flags.unsynchronisation.a = 1
error: expected an object but got: boolean (false)
mp3> .headers[0].flags.unsynchronisation[0] = 1
mp3> .headers[0].header.flags.unsynchronisation[0] = 1
error: expected an array but got: boolean (false)
mp3> .headers[0].flags.unsynchronisation.a |= empty
mp3> .headers[0].header.flags.unsynchronisation.a |= empty
error: expected an object but got: boolean
mp3> .headers[0].flags.unsynchronisation[0] |= empty
mp3> .headers[0].header.flags.unsynchronisation[0] |= empty
error: expected an array but got: boolean
mp3> .headers[0].flags.unsynchronisation | setpath(["a"]; 1)
mp3> .headers[0].header.flags.unsynchronisation | setpath(["a"]; 1)
error: expected an object but got: boolean (false)
mp3> .headers[0].flags.unsynchronisation | setpath([0]; 1)
mp3> .headers[0].header.flags.unsynchronisation | setpath([0]; 1)
error: expected an array but got: boolean (false)
mp3> .headers[0].flags.unsynchronisation | delpaths([["a"]])
mp3> .headers[0].header.flags.unsynchronisation | delpaths([["a"]])
error: expected an object but got: boolean (false)
mp3> .headers[0].flags.unsynchronisation | delpaths([[0]])
mp3> .headers[0].header.flags.unsynchronisation | delpaths([[0]])
error: expected an array but got: boolean (false)
mp3> ^D

View File

@ -1,113 +1,114 @@
$ fq -i -d mp3 . test.mp3
mp3> .headers[0].version | ., tovalue, toactual, tosym, type, length?
mp3> .headers[0].header.version | ., tovalue, toactual, tosym, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 04 | . |.headers[0].version: 4
0x0| 04 | . |.headers[0].header.version: 4 (valid)
4
4
null
"number"
4
mp3> .headers[0].version[0] | ., type, length?
mp3> .headers[0].header.version[0] | ., type, length?
error: expected an array but got: number
mp3> .headers[0].version[-1000] | ., type, length?
mp3> .headers[0].header.version[-1000] | ., type, length?
error: expected an array but got: number
mp3> .headers[0].version[1000] | ., type, length?
mp3> .headers[0].header.version[1000] | ., type, length?
error: expected an array but got: number
mp3> .headers[0].version[1:3] | ., type, length?
mp3> .headers[0].header.version[1:3] | ., type, length?
error: expected an array but got: number
mp3> .headers[0].version[0:-1] | ., type, length?
mp3> .headers[0].header.version[0:-1] | ., type, length?
error: expected an array but got: number
mp3> .headers[0].version[-1000:2000] | ., type, length?
mp3> .headers[0].header.version[-1000:2000] | ., type, length?
error: expected an array but got: number
mp3> .headers[0].version["test"] | ., type, length?
mp3> .headers[0].header.version["test"] | ., type, length?
error: expected an object but got: number
mp3> [.headers[0].version[]] | type, length?
mp3> [.headers[0].header.version[]] | type, length?
error: cannot iterate over: number
mp3> .headers[0].version | keys
mp3> .headers[0].header.version | keys
error: keys cannot be applied to: number
mp3> .headers[0].version | has("a")
mp3> .headers[0].header.version | has("a")
error: has cannot be applied to: number
mp3> .headers[0].version | has(0)
mp3> .headers[0].header.version | has(0)
error: has cannot be applied to: number
mp3> .headers[0].version | type
mp3> .headers[0].header.version | type
"number"
mp3> .headers[0].version | tonumber
mp3> .headers[0].header.version | tonumber
4
mp3> .headers[0].version | tostring
mp3> .headers[0].header.version | tostring
"4"
mp3> .headers[0].version + ""
mp3> .headers[0].header.version + ""
error: cannot add: number (4) and string ("")
mp3> .headers[0].version + 1
mp3> .headers[0].header.version + 1
5
mp3> .headers[0].version._start | ., type, length?
mp3> .headers[0].header.version._start | ., type, length?
24
"number"
24
mp3> .headers[0].version._stop | ., type, length?
mp3> .headers[0].header.version._stop | ., type, length?
32
"number"
32
mp3> .headers[0].version._len | ., type, length?
mp3> .headers[0].header.version._len | ., type, length?
8
"number"
8
mp3> .headers[0].version._name | ., type, length?
mp3> .headers[0].header.version._name | ., type, length?
"version"
"string"
7
mp3> .headers[0].version._actual | ., type, length?
mp3> .headers[0].header.version._actual | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 04 | . |.headers[0].version: 4
0x0| 04 | . |.headers[0].header.version: 4 (valid)
"number"
4
mp3> .headers[0].version._sym | ., type, length?
mp3> .headers[0].header.version._sym | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 04 | . |.headers[0].version: 4
0x0| 04 | . |.headers[0].header.version: 4 (valid)
"null"
0
mp3> .headers[0].version._description | ., type, length?
null
"null"
0
mp3> .headers[0].version._path | ., type, length?
mp3> .headers[0].header.version._description | ., type, length?
"valid"
"string"
5
mp3> .headers[0].header.version._path | ., type, length?
[
"headers",
0,
"header",
"version"
]
"array"
3
mp3> .headers[0].version._bits | ., type, length?
4
mp3> .headers[0].header.version._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 04 | . |.: raw bits 0x3-0x3.7 (1)
"string"
8
mp3> .headers[0].version._bytes | ., type, length?
mp3> .headers[0].header.version._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 04 | . |.: raw bits 0x3-0x3.7 (1)
"string"
1
mp3> .headers[0].version._error | ., type, length?
mp3> .headers[0].header.version._error | ., type, length?
null
"null"
0
mp3> .headers[0].version._gap | ., type, length?
mp3> .headers[0].header.version._gap | ., type, length?
false
"boolean"
mp3> .headers[0].version.a = 1
mp3> .headers[0].header.version.a = 1
error: expected an object but got: number (4)
mp3> .headers[0].version[0] = 1
mp3> .headers[0].header.version[0] = 1
error: expected an array but got: number (4)
mp3> .headers[0].version.a |= empty
mp3> .headers[0].header.version.a |= empty
error: expected an object but got: number
mp3> .headers[0].version[0] |= empty
mp3> .headers[0].header.version[0] |= empty
error: expected an array but got: number
mp3> .headers[0].version | setpath(["a"]; 1)
mp3> .headers[0].header.version | setpath(["a"]; 1)
error: expected an object but got: number (4)
mp3> .headers[0].version | setpath([0]; 1)
mp3> .headers[0].header.version | setpath([0]; 1)
error: expected an array but got: number (4)
mp3> .headers[0].version | delpaths([["a"]])
mp3> .headers[0].header.version | delpaths([["a"]])
error: expected an object but got: number (4)
mp3> .headers[0].version | delpaths([[0]])
mp3> .headers[0].header.version | delpaths([[0]])
error: expected an array but got: number (4)
mp3> ^D

View File

@ -1,6 +1,6 @@
$ fq -i -d mp3 . test.mp3
mp3> .headers[0].flags | ., tovalue, toactual, tosym, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].flags{}:
mp3> .headers[0].header.flags | ., tovalue, toactual, tosym, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.headers[0].header.flags{}:
0x0| 00 | . | unsynchronisation: false
0x0| 00 | . | extended_header: false
0x0| 00 | . | experimental_indicator: false
@ -15,100 +15,101 @@ null
null
"object"
4
mp3> .headers[0].flags[0] | ., type, length?
mp3> .headers[0].header.flags[0] | ., type, length?
error: expected an array with index 0 but got: object
mp3> .headers[0].flags[-1000] | ., type, length?
mp3> .headers[0].header.flags[-1000] | ., type, length?
error: expected an array with index -2 but got: object
mp3> .headers[0].flags[1000] | ., type, length?
mp3> .headers[0].header.flags[1000] | ., type, length?
error: expected an array with index -1 but got: object
mp3> .headers[0].flags[1:3] | ., type, length?
mp3> .headers[0].header.flags[1:3] | ., type, length?
error: expected an array but got: object
mp3> .headers[0].flags[0:-1] | ., type, length?
mp3> .headers[0].header.flags[0:-1] | ., type, length?
error: expected an array but got: object
mp3> .headers[0].flags[-1000:2000] | ., type, length?
mp3> .headers[0].header.flags[-1000:2000] | ., type, length?
error: expected an array but got: object
mp3> .headers[0].flags["test"] | ., type, length?
mp3> .headers[0].header.flags["test"] | ., type, length?
null
"null"
0
mp3> [.headers[0].flags[]] | type, length?
mp3> [.headers[0].header.flags[]] | type, length?
"array"
4
mp3> .headers[0].flags | keys
mp3> .headers[0].header.flags | keys
[
"unsynchronisation",
"extended_header",
"experimental_indicator",
"unused"
]
mp3> .headers[0].flags | has("a")
mp3> .headers[0].header.flags | has("a")
false
mp3> .headers[0].flags | has(0)
mp3> .headers[0].header.flags | has(0)
error: cannot check whether object has a key: 0
mp3> .headers[0].flags | type
mp3> .headers[0].header.flags | type
"object"
mp3> .headers[0].flags | tonumber
mp3> .headers[0].header.flags | tonumber
error: tonumber cannot be applied to: object
mp3> .headers[0].flags | tostring
mp3> .headers[0].header.flags | tostring
"{\"experimental_indicator\":false,\"extended_header\":false,\"unsynchronisation\":false,\"unused\":0}"
mp3> .headers[0].flags + ""
mp3> .headers[0].header.flags + ""
error: cannot add: object ({"experimental_indicator" ...}) and string ("")
mp3> .headers[0].flags + 1
mp3> .headers[0].header.flags + 1
error: cannot add: object ({"experimental_indicator" ...}) and number (1)
mp3> .headers[0].flags._start | ., type, length?
mp3> .headers[0].header.flags._start | ., type, length?
40
"number"
40
mp3> .headers[0].flags._stop | ., type, length?
mp3> .headers[0].header.flags._stop | ., type, length?
48
"number"
48
mp3> .headers[0].flags._len | ., type, length?
mp3> .headers[0].header.flags._len | ., type, length?
8
"number"
8
mp3> .headers[0].flags._name | ., type, length?
mp3> .headers[0].header.flags._name | ., type, length?
"flags"
"string"
5
mp3> .headers[0].flags._actual | ., type, length?
mp3> .headers[0].header.flags._actual | ., type, length?
null
"null"
0
mp3> .headers[0].flags._sym | ., type, length?
mp3> .headers[0].header.flags._sym | ., type, length?
null
"null"
0
mp3> .headers[0].flags._description | ., type, length?
mp3> .headers[0].header.flags._description | ., type, length?
null
"null"
0
mp3> .headers[0].flags._path | ., type, length?
mp3> .headers[0].header.flags._path | ., type, length?
[
"headers",
0,
"header",
"flags"
]
"array"
3
mp3> .headers[0].flags._bits | ., type, length?
4
mp3> .headers[0].header.flags._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.: raw bits 0x5-0x5.7 (1)
"string"
8
mp3> .headers[0].flags._bytes | ., type, length?
mp3> .headers[0].header.flags._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0| 00 | . |.: raw bits 0x5-0x5.7 (1)
"string"
1
mp3> .headers[0].flags._error | ., type, length?
mp3> .headers[0].header.flags._error | ., type, length?
null
"null"
0
mp3> .headers[0].flags._gap | ., type, length?
mp3> .headers[0].header.flags._gap | ., type, length?
false
"boolean"
mp3> .headers[0].flags.a = 1
mp3> .headers[0].header.flags.a = 1
{
"footers": [],
"frames": [
@ -437,13 +438,6 @@ mp3> .headers[0].flags.a = 1
],
"headers": [
{
"flags": {
"a": 1,
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
},
"frames": [
{
"flags": {
@ -465,17 +459,26 @@ mp3> .headers[0].flags.a = 1
"text_encoding": "utf8"
}
],
"magic": "ID3",
"padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"revision": 0,
"size": 35,
"version": 4
"header": {
"flags": {
"a": 1,
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
},
"magic": "ID3",
"revision": 0,
"size": 35,
"version": 4
},
"padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
}
]
}
mp3> .headers[0].flags[0] = 1
mp3> .headers[0].header.flags[0] = 1
error: expected an array but got: object ({"experimental_indicator" ...})
mp3> .headers[0].flags.a |= empty
mp3> .headers[0].header.flags.a |= empty
{
"footers": [],
"frames": [
@ -804,12 +807,6 @@ mp3> .headers[0].flags.a |= empty
],
"headers": [
{
"flags": {
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
},
"frames": [
{
"flags": {
@ -831,17 +828,25 @@ mp3> .headers[0].flags.a |= empty
"text_encoding": "utf8"
}
],
"magic": "ID3",
"padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
"revision": 0,
"size": 35,
"version": 4
"header": {
"flags": {
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
},
"magic": "ID3",
"revision": 0,
"size": 35,
"version": 4
},
"padding": "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000"
}
]
}
mp3> .headers[0].flags[0] |= empty
mp3> .headers[0].header.flags[0] |= empty
error: expected an array with index 0 but got: object
mp3> .headers[0].flags | setpath(["a"]; 1)
mp3> .headers[0].header.flags | setpath(["a"]; 1)
{
"a": 1,
"experimental_indicator": false,
@ -849,15 +854,15 @@ mp3> .headers[0].flags | setpath(["a"]; 1)
"unsynchronisation": false,
"unused": 0
}
mp3> .headers[0].flags | setpath([0]; 1)
mp3> .headers[0].header.flags | setpath([0]; 1)
error: expected an array but got: object ({"experimental_indicator" ...})
mp3> .headers[0].flags | delpaths([["a"]])
mp3> .headers[0].header.flags | delpaths([["a"]])
{
"experimental_indicator": false,
"extended_header": false,
"unsynchronisation": false,
"unused": 0
}
mp3> .headers[0].flags | delpaths([[0]])
mp3> .headers[0].header.flags | delpaths([[0]])
error: expected an array but got: object ({"experimental_indicator" ...})
mp3> ^D

View File

@ -1,125 +1,126 @@
$ fq -i -d mp3 . test.mp3
mp3> .headers[0].magic | ., tovalue, toactual, tosym, type, length?
mp3> .headers[0].header.magic | ., tovalue, toactual, tosym, type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
"ID3"
"ID3"
null
"string"
3
mp3> .headers[0].magic[0] | ., type, length?
mp3> .headers[0].header.magic[0] | ., type, length?
"I"
"string"
1
mp3> .headers[0].magic[-1000] | ., type, length?
mp3> .headers[0].header.magic[-1000] | ., type, length?
""
"string"
0
mp3> .headers[0].magic[1000] | ., type, length?
mp3> .headers[0].header.magic[1000] | ., type, length?
""
"string"
0
mp3> .headers[0].magic[1:3] | ., type, length?
mp3> .headers[0].header.magic[1:3] | ., type, length?
"D3"
"string"
2
mp3> .headers[0].magic[0:-1] | ., type, length?
mp3> .headers[0].header.magic[0:-1] | ., type, length?
"ID"
"string"
2
mp3> .headers[0].magic[-1000:2000] | ., type, length?
mp3> .headers[0].header.magic[-1000:2000] | ., type, length?
"ID3"
"string"
3
mp3> .headers[0].magic["test"] | ., type, length?
mp3> .headers[0].header.magic["test"] | ., type, length?
error: expected an object but got: string
mp3> [.headers[0].magic[]] | type, length?
mp3> [.headers[0].header.magic[]] | type, length?
error: cannot iterate over: string
mp3> .headers[0].magic | keys
mp3> .headers[0].header.magic | keys
error: keys cannot be applied to: string
mp3> .headers[0].magic | has("a")
mp3> .headers[0].header.magic | has("a")
error: has cannot be applied to: string
mp3> .headers[0].magic | has(0)
mp3> .headers[0].header.magic | has(0)
error: has cannot be applied to: string
mp3> .headers[0].magic | type
mp3> .headers[0].header.magic | type
"string"
mp3> .headers[0].magic | tonumber
mp3> .headers[0].header.magic | tonumber
error: invalid number: "ID3"
mp3> .headers[0].magic | tostring
mp3> .headers[0].header.magic | tostring
"ID3"
mp3> .headers[0].magic + ""
mp3> .headers[0].header.magic + ""
"ID3"
mp3> .headers[0].magic + 1
mp3> .headers[0].header.magic + 1
error: cannot add: string ("ID3") and number (1)
mp3> .headers[0].magic._start | ., type, length?
mp3> .headers[0].header.magic._start | ., type, length?
0
"number"
0
mp3> .headers[0].magic._stop | ., type, length?
mp3> .headers[0].header.magic._stop | ., type, length?
24
"number"
24
mp3> .headers[0].magic._len | ., type, length?
mp3> .headers[0].header.magic._len | ., type, length?
24
"number"
24
mp3> .headers[0].magic._name | ., type, length?
mp3> .headers[0].header.magic._name | ., type, length?
"magic"
"string"
5
mp3> .headers[0].magic._actual | ., type, length?
mp3> .headers[0].header.magic._actual | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
"string"
3
mp3> .headers[0].magic._sym | ., type, length?
mp3> .headers[0].header.magic._sym | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.headers[0].magic: "ID3" (valid)
0x0|49 44 33 |ID3 |.headers[0].header.magic: "ID3" (valid)
"null"
0
mp3> .headers[0].magic._description | ., type, length?
mp3> .headers[0].header.magic._description | ., type, length?
"valid"
"string"
5
mp3> .headers[0].magic._path | ., type, length?
mp3> .headers[0].header.magic._path | ., type, length?
[
"headers",
0,
"header",
"magic"
]
"array"
3
mp3> .headers[0].magic._bits | ., type, length?
4
mp3> .headers[0].header.magic._bits | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.: raw bits 0x0-0x2.7 (3)
"string"
24
mp3> .headers[0].magic._bytes | ., type, length?
mp3> .headers[0].header.magic._bytes | ., type, length?
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|
0x0|49 44 33 |ID3 |.: raw bits 0x0-0x2.7 (3)
"string"
3
mp3> .headers[0].magic._error | ., type, length?
mp3> .headers[0].header.magic._error | ., type, length?
null
"null"
0
mp3> .headers[0].magic._gap | ., type, length?
mp3> .headers[0].header.magic._gap | ., type, length?
false
"boolean"
mp3> .headers[0].magic.a = 1
mp3> .headers[0].header.magic.a = 1
error: expected an object but got: string ("ID3")
mp3> .headers[0].magic[0] = 1
mp3> .headers[0].header.magic[0] = 1
error: expected an array but got: string ("ID3")
mp3> .headers[0].magic.a |= empty
mp3> .headers[0].header.magic.a |= empty
error: expected an object but got: string
mp3> .headers[0].magic[0] |= empty
mp3> .headers[0].header.magic[0] |= empty
error: expected an array but got: string ("ID3")
mp3> .headers[0].magic | setpath(["a"]; 1)
mp3> .headers[0].header.magic | setpath(["a"]; 1)
error: expected an object but got: string ("ID3")
mp3> .headers[0].magic | setpath([0]; 1)
mp3> .headers[0].header.magic | setpath([0]; 1)
error: expected an array but got: string ("ID3")
mp3> .headers[0].magic | delpaths([["a"]])
mp3> .headers[0].header.magic | delpaths([["a"]])
error: expected an object but got: string ("ID3")
mp3> .headers[0].magic | delpaths([[0]])
mp3> .headers[0].header.magic | delpaths([[0]])
error: expected an array but got: string ("ID3")
mp3> ^D

View File

@ -1,10 +1,10 @@
#!/bin/sh
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers/g' | sed 's/PROMPT/mp3/g' >value_array.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].flags.unsynchronisation/g' | sed 's/PROMPT/mp3/g' >value_boolean.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].header.flags.unsynchronisation/g' | sed 's/PROMPT/mp3/g' >value_boolean.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].padding/g' | sed 's/PROMPT/mp3/g' >value_null.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].version/g' | sed 's/PROMPT/mp3/g' >value_number.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].flags/g' | sed 's/PROMPT/mp3/g' >value_object.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].magic/g' | sed 's/PROMPT/mp3/g' >value_string.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].header.version/g' | sed 's/PROMPT/mp3/g' >value_number.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].header.flags/g' | sed 's/PROMPT/mp3/g' >value_object.fqtest
sed 's/CMD/fq -i -d mp3 . test.mp3/g' <value_t.fqtest.tmpl | sed 's/EXPR/.headers[0].header.magic/g' | sed 's/PROMPT/mp3/g' >value_string.fqtest
sed "s/CMD/fq -i -n '\"[]\" | json'/g" <value_t.fqtest.tmpl | sed 's/EXPR/(.)/g' | sed 's/PROMPT/json/g' >value_json_array.fqtest
sed "s/CMD/fq -i -n '\"{}\" | json'/g" <value_t.fqtest.tmpl | sed 's/EXPR/(.)/g' | sed 's/PROMPT/json/g' >value_json_object.fqtest