{"id":28178240,"url":"https://github.com/redbluevideo/hvml","last_synced_at":"2025-06-24T23:33:28.933Z","repository":{"id":32848412,"uuid":"132178452","full_name":"RedBlueVideo/hvml","owner":"RedBlueVideo","description":"HVML Parser for Node.js","archived":false,"fork":false,"pushed_at":"2025-05-25T05:57:28.000Z","size":1713,"stargazers_count":0,"open_issues_count":15,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-25T06:37:14.867Z","etag":null,"topics":["hvml","hypermedia","hypervideo"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RedBlueVideo.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":"2018-05-04T19:01:28.000Z","updated_at":"2025-05-25T05:57:32.000Z","dependencies_parsed_at":"2025-05-25T06:42:30.685Z","dependency_job_id":null,"html_url":"https://github.com/RedBlueVideo/hvml","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/RedBlueVideo/hvml","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RedBlueVideo%2Fhvml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RedBlueVideo%2Fhvml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RedBlueVideo%2Fhvml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RedBlueVideo%2Fhvml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RedBlueVideo","download_url":"https://codeload.github.com/RedBlueVideo/hvml/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RedBlueVideo%2Fhvml/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261775672,"owners_count":23207968,"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":["hvml","hypermedia","hypervideo"],"created_at":"2025-05-16T01:11:53.438Z","updated_at":"2025-06-24T23:33:28.897Z","avatar_url":"https://github.com/RedBlueVideo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hvml\n[HVML](https://hvml.redblue.video) Parser for Node.js\n\n[![Build Status](https://api.travis-ci.com/RedBlueVideo/hvml.svg?branch=master)](https://travis-ci.com/RedBlueVideo/hvml) [![Code Coverage](https://img.shields.io/codecov/c/github/RedBlueVideo/hvml/master.svg)](https://codecov.io/gh/RedBlueVideo/hvml/) [![Downloads per month (NPM)](https://img.shields.io/npm/dm/hvml.svg)](https://www.npmjs.com/package/hvml)\n\nHVML (Hypervideo Markup Language) is a video metadata vocabulary. It covers three main classes of metadata:\n- Technical details, like the available resolutions or codecs of a media file;\n- Artistic details, like who appears in a given movie or what awards it has won; and\n- Interactive UI instructions for compatible video players such as [RedBlue](https://github.com/RedBlueVideo/redblue).\n\nHVML is designed to be human-friendly enough to write by hand in most cases. This library is not required in order to use it; it just provides an imperative API for working with it programmatically.\n\n## Installation\n```shell\nyarn add hvml\n```\nor\n```shell\nnpm install hvml\n```\n\n## Example Usage\n\n```js\nconst { HVML, Video } = require( 'hvml' );\n\nconst hvml = new HVML( './hvml.xml' );\nhvml.ready.then( () =\u003e {\n  // Instance methods available now\n  console.log( hvml.toJson() );\n} );\n\nconst video = new Video( {\n  \"type\": [\"personal\", \"documentary\"],\n  \"lang\": \"en-US\",\n  \"id\": \"welcome-to-my-channel\",\n} );\nvideo.setTitle( 'Welcome to My Channel!' );\nvideo.setTitle( 'チャンネルへようこそ！', 'ja' );\n// The Video types `personal` and `documentary` combine\n// to create an implicit \"vlog episode\" semantic.\nconsole.log( video.isVlogEpisode() ); // true\n```\n\n## API\n\n### HVML\n\nA Class representing the [`hvml` root element](https://hvml.redblue.video/elements/hvml/).\n\n#### Constructor: `new HVML(path, [config])`\n\n- `path`: HVML file to be read.\n- `config`: (optional) Configuration object with keys:\n  - `schemaPath` Path to validation schema. Defaults to `rng/hvml.rng` (relative to `node_modules/hvml/`).\n  - `schemaType`: Type of validation schema, `rng` for RELAX NG or `xsd` for XML Schema Definition. Currently only `rng` is supported. Defaults to `rng`.\n  - `encoding`: `readFile` character encoding. Defaults to `utf8`.\n\nReturns \u003cb\u003eObject\u003c/b\u003e, an instance of `HVML`.\n\n#### Instance Properties\n\n##### `.ready`\n\n\u003cb\u003ePromise\u003c/b\u003e that resolves when your HVML file and the internal schema used for validation are both successfully read from the file system.\n\nThe Promise itself returns a [libxmljs](https://github.com/libxmljs/libxmljs) object representing the XML tree of the file. This object is also accessible as the instance property `.xml`, so you don’t need to capture it on your first `then()`.\n\n##### `.xml`\n\n\u003cb\u003eObject\u003c/b\u003e representing the XML tree of your HVML file, as returned from [libxmljs](https://github.com/libxmljs/libxmljs).\n\nThis is mostly just used internally but it’s provided as a convenience for custom operations.\n\n##### `.hvmlPath`\n\n\u003cb\u003eString\u003c/b\u003e. The HVML file path specified in the constructor.\n\n#### Instance Methods\n\n##### `.toJson()`\n\nTransforms the current HVML tree to its JSON representation (i.e. an object literal).\n\nReturns \u003cb\u003eObject\u003c/b\u003e.\n\n##### `.validate([xmllintPath])`\nValidates the HVML file against an internal RELAX NG schema.\n\n- `xmllintPath`: Path where Node can find `xmllint`¹. Defaults to `xmllint` (which assumes it is somewhere in your system’s `$PATH`, such as `/usr/bin/`).\n\nReturns a Promise that\n- Resolves to `true` on validation success; or\n- Rejects with an `object` on validation error, for example:\n```json\n  {\n    \"message\": \"./bad.hvml:3: element ovml: Relax-NG validity error : Expecting element hvml, got ovml\",\n    \"error\": \"Expecting element hvml, got ovml\",\n    \"file\": \"./bad.hvml\",\n    \"line\": \"3\",\n    \"type\": \"validity\",\n    \"expecting\": \"hvml\",\n    \"got\": \"ovml\"\n  }\n```\n\n¹ `xmllint` is a command-line tool written in C which performs XML validation according to schema rules. Due to the added complexity of porting this utility to JavaScript, `.validate()` currently requires the `xmllint` binary to be installed on your system and available to Node. It comes bundled with `libxml2`, which you may already have if you work with XML a lot.\n\nIf you don’t have `libxml2` installed, you must [download it](http://xmlsoft.org/downloads.html) and compile the source code using the following steps:\n\n```shell\ncd libxml2/\n./autogen.sh\nconfigure\nmake\nmake install\n```\n\nWe realize this is a pain but we’d rather ship the feature than be blocked by a lack of C/C++ experience. Pull requests welcome!\n\n### Video\n\nA Class representing a [`video` element](https://hvml.redblue.video/elements/video/).\n\n#### Constructor: `new Video([config])`\n\n- `config`: (optional) Configuration object with keys:\n  - `type`: Space-separated string or array containing valid video types (`narrative`, `documentary`, `ad`, `personal`, `historical`).\n  - `lang`: A [BCP 47](https://tools.ietf.org/html/bcp47) language/region tag, e.g. `en` or `en-US`.\n  - `id`: An XML/HTML-style unique ID for querying.\n\nReturns \u003cb\u003eObject\u003c/b\u003e, an instance of `Video`.\n\n##### Example\n\n```js\nconst { Video } = require( 'hvml' );\nconst video = new Video( {\n  \"type\": [\"personal\", \"documentary\"],\n  \"lang\": \"en-US\",\n  \"id\": \"welcome-to-my-channel\",\n} );\n```\n\n#### Static Methods\n\n##### `isValidType(type)`\n\nChecks if the given video type is allowed in HVML.\n\n- `type`: String of individual type to check.\n\nReturns \u003cb\u003eBoolean\u003c/b\u003e.\n\n##### Example\n\n```js\nconst { Video } = require( 'hvml' );\nconsole.log( Video.isValidType( 'narrative' ) ); // true\nconsole.log( Video.isValidType( 'big-chungus' ) ); // false\n```\n\n#### Instance Methods\n\n##### `hasType(type)`\n\nChecks if a `Video` object has a given type set.\n\nReturns \u003cb\u003eBoolean\u003c/b\u003e.\n\n##### Example\n\n```js\nconst { Video } = require( 'hvml' );\nconst video = new Video( {\n  \"type\": [\"personal\", \"documentary\"],\n  \"lang\": \"en-US\",\n  \"id\": \"welcome-to-my-channel\",\n} );\nconsole.log( Video.hasType( 'documentary' ) ); // true\nconsole.log( Video.hasType( 'ad' ) ); // false\n```\n\n##### `isVlogEpisode()`\n\nConvenience method. Checks if a `Video` object contains the special type combination `personal` + `documentary`.\n\nReturns \u003cb\u003eBoolean\u003c/b\u003e.\n\n##### Example\n\n```js\nconst { Video } = require( 'hvml' );\nconst video = new Video( {\n  \"type\": [\"personal\", \"documentary\"],\n  \"lang\": \"en-US\",\n  \"id\": \"welcome-to-my-channel\",\n} );\nconsole.log( video.isVlogEpisode() ); // true\n```\n\n##### `isArchived()`\n\nConvenience method. Checks if a `Video` object contains the special type combination `personal` + `historical`.\n\nReturns \u003cb\u003eBoolean\u003c/b\u003e.\n\n##### Example\n\n```js\nconst { Video } = require( 'hvml' );\nconst video = new Video( {\n  \"type\": [\"personal\", \"historical\"],\n  \"lang\": \"en-US\",\n  \"id\": \"welcome-to-my-channel\",\n} );\nconsole.log( video.isArchived() ); // true\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredbluevideo%2Fhvml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fredbluevideo%2Fhvml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fredbluevideo%2Fhvml/lists"}