{"id":16688157,"url":"https://github.com/freestrings/rtag","last_synced_at":"2025-05-15T08:32:11.488Z","repository":{"id":57663890,"uuid":"77824293","full_name":"freestrings/rtag","owner":"freestrings","description":"ID3 read and write library written in rustlang","archived":false,"fork":false,"pushed_at":"2017-04-17T14:06:58.000Z","size":10746,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-03T05:51:14.491Z","etag":null,"topics":["id3","id3v1","id3v2","library","mp3","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/freestrings.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-02T09:55:37.000Z","updated_at":"2023-08-30T14:55:09.000Z","dependencies_parsed_at":"2022-08-28T00:12:13.741Z","dependency_job_id":null,"html_url":"https://github.com/freestrings/rtag","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freestrings%2Frtag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freestrings%2Frtag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freestrings%2Frtag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/freestrings%2Frtag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/freestrings","download_url":"https://codeload.github.com/freestrings/rtag/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254304641,"owners_count":22048446,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["id3","id3v1","id3v2","library","mp3","rust"],"created_at":"2024-10-12T15:27:04.435Z","updated_at":"2025-05-15T08:32:06.474Z","avatar_url":"https://github.com/freestrings.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Why\n\nTo learn rust!\n\n- This library is used for console based `ID3 tagging` tool [Markdang](https://github.com/freestrings/markdang).\n\n# Usage\n\nThis is `ID3` read and write library.\n\n- [Add dependency](#add-dependency)\n- [Reding: How to read `ID3` information](#reding-how-to-read-id3-information)\n- [Writing: How to write `ID3` information](#writing-how-to-write-id3-information)\n- [Rewrite: How to rewrite all `ID3` information to version 4](#rewrite-how-to-rewrite-a-id3-information-to-version-4)\n- [Getting information of a frame body without property name.](#getting-information-of-a-frame-body-without-property-name)\n\nother usecases [See tests](./tests/metadata.rs).\n\n## Add dependency\n\nThis can be used by adding `rtag` to your dependencies in your project's `Cargo.toml`\n\n```toml\n[dependencies]\nrtag = \"0.3.5\"\n```\nand this to your crate root:\n\n```rust\nextern crate rtag;\n```\n\n## Reding: How to read `ID3` information\n\nTo read a `ID3` metadata, you use a [MetadataReader](./src/metadata.rs#L50) and a [Unit](./src/metadata.rs#L36) enum. \n\n\nand the `MetadataReader` is implementing the [std::iter::Iterator](https://doc.rust-lang.org/std/iter/trait.Iterator.html) trait, \nyou can use [filter](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter), [map](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map), [fold](https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold).. and so on.\n\n### Example\n\n```rust\n// read a frame1\nfor m in MetadataReader::new(\"./test-resources/v1-v2.mp3\").unwrap() {\n    match m {\n        Unit::FrameV1(frame) =\u003e {\n            debug!(\"v1: {:?}\", frame);\n            assert_eq!(\"Artist\", frame.artist);\n            assert_eq!(\"!@#$\", frame.comment);\n            assert_eq!(\"1\", frame.track);\n            assert_eq!(\"137\", frame.genre);\n        }\n        _ =\u003e (),\n    }\n}\n\n// filter a frame v3 having `compression flag`\nlet mut i = MetadataReader::new(path).unwrap().filter(|m| match m {\n    \u0026Unit::FrameV2(FrameHeader::V23(ref header), _) =\u003e {\n        header.has_flag(FrameHeaderFlag::Compression)\n    }\n    _ =\u003e false,\n});\n\n// fold a frame v2\nlet new_data = MetadataReader::new(path)\n    .unwrap()\n    .fold(Vec::new(), |mut vec, unit| {\n        if let Unit::FrameV2(frame_head, frame_body) = unit {\n            let new_frame_body = if let FrameBody::TALB(ref frame) = frame_body {\n                let mut new_frame = frame.clone();\n                new_frame.text = \"Album!\".to_string();\n                FrameBody::TALB(new_frame)\n            } else {\n                frame_body.clone()\n            };\n\n            vec.push(Unit::FrameV2(frame_head, new_frame_body));\n        } else {\n            vec.push(unit);\n        }\n\n        vec\n    });\n```\n\n## Writing: How to write `ID3` information \n\nTo write a `ID3` metadata, you pass [FrameHeader](./src/frame.rs#L267) and [FrameBody](./src/frame.rs#L2022) to [MetadataWriter](./src/metadata.rs#L366) via [std::vec::Vec](https://doc.rust-lang.org/std/vec/struct.Vec.html).\n\n### Example\n\n```rust\nlet new_data = MetadataReader::new(path)\n    .unwrap()\n    .fold(Vec::new(), |mut vec, unit| {\n        if let Unit::FrameV2(frame_head, frame_body) = unit {\n            let new_frame_body = ...\n            vec.push(Unit::FrameV2(frame_head, new_frame_body));\n        }\n\n        vec\n    });\n\nlet _ = MetadataWriter::new(path).unwrap().write(new_data, false);\n```\n\n## Rewrite: How to rewrite a `ID3` information to version 4\n\nTo rewrite all the frames to version 4, it is same to above example but second parameter is `true`. \n\u003e Note: the frame v1 information is ignored and some frames that are ignored.\n\u003e - In 2.2 'CRM', 'PIC'. \n\u003e - In 2.3 'EQUA', 'IPLS', 'RVAD', 'TDAT', 'TIME', 'TORY', 'TRDA', 'TSIZ', 'TYER'\n\n```rust\n// collect frames having version 2\nlet frames = MetadataReader::new(path).unwrap().collect::\u003cVec\u003cUnit\u003e\u003e();\n// rewrite to version 4\nlet _ = MetadataWriter::new(path).unwrap().write(frames, true);\n// read a version 4\nfor unit in MetadataReader::new(path).unwrap() {\n    match unit {\n        Unit::FrameV2(FrameHeader::V24(head), frame_body) =\u003e {\n            ...\n        },\n        _ =\u003e (),\n    }\n}\n```\n\n## Getting information of a frame body without property name.\n\nTo read value of frame without property name, FrameBody support `to_map` and `inside`.\n\n### Example\n\n```rust\nfor unit in MetadataReader::new(path).unwrap() {\n    match unit {\n        Unit::FrameV2(_, ref frame_body) =\u003e {\n            \n            // 1. using to_map();\n            let map = frame_body.to_map();\n            //{\n            //    \u003ckey1:\u0026str\u003e: \u003cvalue1:String\u003e\n            //    ...\n            //}\n\n            // 2. using inside\n            frame_body.inside(|key, value| {\n                // key\u003c\u0026str\u003e, value\u003cString\u003e\n                ...\n\n                true // if true, look inside next.\n            })\n\n        },\n        _ =\u003e (),\n    }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreestrings%2Frtag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffreestrings%2Frtag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffreestrings%2Frtag/lists"}