{"id":13600228,"url":"https://github.com/abema/go-mp4","last_synced_at":"2026-01-12T15:52:13.411Z","repository":{"id":38070417,"uuid":"232823899","full_name":"abema/go-mp4","owner":"abema","description":"Go library for reading and writing MP4 file","archived":false,"fork":false,"pushed_at":"2025-03-24T07:55:04.000Z","size":985,"stargazers_count":490,"open_issues_count":4,"forks_count":34,"subscribers_count":29,"default_branch":"master","last_synced_at":"2025-04-10T21:38:23.727Z","etag":null,"topics":["fmp4","go","golang","mp4","mp4box"],"latest_commit_sha":null,"homepage":"https://dev.to/sunfishshogi/go-mp4-golang-library-and-cli-tool-for-mp4-52o1","language":"Go","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/abema.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-01-09T14:09:33.000Z","updated_at":"2025-04-08T21:25:33.000Z","dependencies_parsed_at":"2024-06-18T12:40:29.558Z","dependency_job_id":"7a934ef5-e713-4460-b9c5-2f4df38a37f5","html_url":"https://github.com/abema/go-mp4","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/abema/go-mp4","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abema%2Fgo-mp4","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abema%2Fgo-mp4/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abema%2Fgo-mp4/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abema%2Fgo-mp4/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abema","download_url":"https://codeload.github.com/abema/go-mp4/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abema%2Fgo-mp4/sbom","scorecard":{"id":160503,"data":{"date":"2025-08-11","repo":{"name":"github.com/abema/go-mp4","commit":"88b57925242fd634eea92da8a24e78d11bee030a"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/17 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":7,"reason":"dependency not pinned by hash detected -- score normalized to 7","details":["Warn: goCommand not pinned by hash: .github/workflows/test.yml:30","Info:   2 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   2 goCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":10,"reason":"project is fuzzed","details":["Info: GoBuiltInFuzzer integration found: read_test.go:263"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":4,"reason":"SAST tool is not run on all commits -- score normalized to 4","details":["Warn: 11 commits out of 24 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-16T13:16:30.255Z","repository_id":38070417,"created_at":"2025-08-16T13:16:30.255Z","updated_at":"2025-08-16T13:16:30.255Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28341884,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T15:50:39.657Z","status":"ssl_error","status_checked_at":"2026-01-12T15:49:49.297Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["fmp4","go","golang","mp4","mp4box"],"created_at":"2024-08-01T18:00:32.862Z","updated_at":"2026-01-12T15:52:13.392Z","avatar_url":"https://github.com/abema.png","language":"Go","funding_links":[],"categories":["Go","HarmonyOS"],"sub_categories":["Windows Manager"],"readme":"go-mp4\n------\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/abema/go-mp4.svg)](https://pkg.go.dev/github.com/abema/go-mp4)\n![Test](https://github.com/abema/go-mp4/actions/workflows/test.yml/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/abema/go-mp4/badge.svg)](https://coveralls.io/github/abema/go-mp4)\n[![Go Report Card](https://goreportcard.com/badge/github.com/abema/go-mp4)](https://goreportcard.com/report/github.com/abema/go-mp4)\n\ngo-mp4 is Go library which provides low-level I/O interfaces of MP4.\nThis library supports you to parse or build any MP4 boxes(atoms) directly.\n\ngo-mp4 provides very flexible interfaces for reading boxes.\nIf you want to read only specific parts of MP4 file, this library extracts those boxes via io.ReadSeeker interface.\n\nOn the other hand, this library is not suitable for complex data conversions.\n\n## Integration with your Go application\n\n### Reading\n\nUsing [ReadBoxStructure](https://pkg.go.dev/github.com/abema/go-mp4#ReadBoxStructure) or [ReadBoxStructureFromInternal](https://pkg.go.dev/github.com/abema/go-mp4#ReadBoxStructureFromInternal), you can scan box(atom) tree by depth-first order.\n\n```go\n// expand all boxes\n_, err := mp4.ReadBoxStructure(file, func(h *mp4.ReadHandle) (interface{}, error) {\n\tfmt.Println(\"depth\", len(h.Path))\n\n\t// Box Type (e.g. \"mdhd\", \"tfdt\", \"mdat\")\n\tfmt.Println(\"type\", h.BoxInfo.Type.String())\n\n\t// Box Size\n\tfmt.Println(\"size\", h.BoxInfo.Size)\n\n\tif h.BoxInfo.IsSupportedType() {\n\t\t// Payload\n\t\tbox, _, err := h.ReadPayload()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tstr, err := mp4.Stringify(box, h.BoxInfo.Context)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfmt.Println(\"payload\", str)\n\n\t\t// Expands children\n\t\treturn h.Expand()\n\t}\n\treturn nil, nil\n})\n```\n\n[ExtractBox](https://pkg.go.dev/github.com/abema/go-mp4#ExtractBox), [ExtractBoxes](https://pkg.go.dev/github.com/abema/go-mp4#ExtractBoxes), [ExtractBoxWithPayload](https://pkg.go.dev/github.com/abema/go-mp4#ExtractBoxWithPayload), [ExtractBoxesWithPayload](https://pkg.go.dev/github.com/abema/go-mp4#ExtractBoxesWithPayload), and [Probe](https://pkg.go.dev/github.com/abema/go-mp4#Probe) are wrapper functions of ReadBoxStructure.\n\n```go\n// extract specific boxes\nboxes, err := mp4.ExtractBoxWithPayload(file, nil, mp4.BoxPath{mp4.BoxTypeMoov(), mp4.BoxTypeTrak(), mp4.BoxTypeTkhd()})\nif err != nil {\n   :\n}\nfor _, box := range boxes {\n  tkhd := box.Payload.(*mp4.Tkhd)\n  fmt.Println(\"track ID:\", tkhd.TrackID)\n}\n```\n\n```go\n// get basic informations\ninfo, err := mp4.Probe(bufseekio.NewReadSeeker(file, 1024, 4))  \nif err != nil {\n   :\n}\nfmt.Println(\"track num:\", len(info.Tracks))\n```\n\n### Writing\n\nWriter helps you to write box tree.\nThe following sample code edits emsg box and writes to another file.\n\n```go\nr := bufseekio.NewReadSeeker(inputFile, 128*1024, 4)\nw := mp4.NewWriter(outputFile)\n_, err = mp4.ReadBoxStructure(r, func(h *mp4.ReadHandle) (interface{}, error) {\n\tswitch h.BoxInfo.Type {\n\tcase mp4.BoxTypeEmsg():\n\t\t// write box size and box type\n\t\t_, err := w.StartBox(\u0026h.BoxInfo)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// read payload\n\t\tbox, _, err := h.ReadPayload()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// update MessageData\n\t\temsg := box.(*mp4.Emsg)\n\t\temsg.MessageData = []byte(\"hello world\")\n\t\t// write box playload\n\t\tif _, err := mp4.Marshal(w, emsg, h.BoxInfo.Context); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// rewrite box size\n\t\t_, err = w.EndBox()\n\t\treturn nil, err\n\tdefault:\n\t\t// copy all\n\t\treturn nil, w.CopyBox(r, \u0026h.BoxInfo)\n\t}\n})\n```\n\nPlease note that the above sample code doesn't work for some MP4 files.\nIf your MP4 files include specific box types (ex. stco, mfra), you should update those when offsets of mdat box changed.\nNext sample code adds an metadata box and updates chunk offsets in stco boxes.\n\n[Sample Code: Insert Metadata and Update stco box](https://gist.github.com/sunfish-shogi/cccde016a38c66d32c07a0234368804e)\n\n### User-defined Boxes\n\nYou can create additional box definition as follows:\n\n```go\nfunc BoxTypeXxxx() BoxType { return mp4.StrToBoxType(\"xxxx\") }\n\nfunc init() {\n\tmp4.AddBoxDef(\u0026Xxxx{}, 0)\n}\n\ntype Xxxx struct {\n\tFullBox  `mp4:\"0,extend\"`\n\tUI32      uint32 `mp4:\"1,size=32\"`\n\tByteArray []byte `mp4:\"2,size=8,len=dynamic\"`\n}\n\nfunc (*Xxxx) GetType() BoxType {\n\treturn BoxTypeXxxx()\n}\n```\n\n### Buffering\n\ngo-mp4 has no buffering feature for I/O.\nIf you should reduce Read function calls, you can wrap the io.ReadSeeker by [bufseekio](https://github.com/sunfish-shogi/bufseekio).\n\n## Command Line Tool\n\nInstall mp4tool as follows:\n\n```sh\ngo install github.com/abema/go-mp4/cmd/mp4tool@latest\n\nmp4tool -help\n```\n\nFor example, `mp4tool dump MP4_FILE_NAME` command prints MP4 box tree as follows:\n\n```\n[moof] Size=504\n  [mfhd] Size=16 Version=0 Flags=0x000000 SequenceNumber=1\n  [traf] Size=480\n    [tfhd] Size=28 Version=0 Flags=0x020038 TrackID=1 DefaultSampleDuration=9000 DefaultSampleSize=33550 DefaultSampleFlags=0x1010000\n    [tfdt] Size=20 Version=1 Flags=0x000000 BaseMediaDecodeTimeV1=0\n    [trun] Size=424 ... (use -a option to show all)\n[mdat] Size=44569 Data=[...] (use -mdat option to expand)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabema%2Fgo-mp4","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabema%2Fgo-mp4","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabema%2Fgo-mp4/lists"}