https://github.com/luanrt/googlevideo
A set of utilities for working with Google Video APIs.
https://github.com/luanrt/googlevideo
googlevideo sabr ump youtube yt-ump
Last synced: 7 months ago
JSON representation
A set of utilities for working with Google Video APIs.
- Host: GitHub
- URL: https://github.com/luanrt/googlevideo
- Owner: LuanRT
- License: mit
- Created: 2024-09-13T16:52:41.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-04T18:34:09.000Z (over 1 year ago)
- Last Synced: 2024-10-10T00:43:24.261Z (over 1 year ago)
- Topics: googlevideo, sabr, ump, youtube, yt-ump
- Language: TypeScript
- Homepage:
- Size: 644 KB
- Stars: 16
- Watchers: 2
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# GoogleVideo
[](https://jsr.io/@luanrt/googlevideo)
[](https://www.npmjs.com/package/googlevideo)
[](./LICENSE)
A collection of modules for working with YouTube's proprietary video streaming protocols (UMP/SABR). It can be used to build clients or to integrate with existing media players (e.g., [Shaka Player](https://shaka-player-demo.appspot.com/docs/api/index.html)).
[API Reference →](https://ytjs.dev/googlevideo/api)
## Installation
```bash
# NPM
npm install googlevideo
# JSR / Deno
npx jsr add @luanrt/googlevideo
deno add jsr:@luanrt/googlevideo
# GitHub
npm install LuanRT/googlevideo
```
## Basic Usage
Below is a basic example using the UMP modules to create a buffer, write parts, and process them:
> [!NOTE]
> More advanced usage examples can be found in the [/examples](./examples/) directory.
```typescript
import { CompositeBuffer, UmpReader, UmpWriter } from 'googlevideo/ump';
import { MediaHeader, UMPPartId } from 'googlevideo/protos';
import { concatenateChunks } from 'googlevideo/utils';
import { Part } from 'googlevideo/shared-types';
function handleMediaHeader(part: Part) {
const mediaHeader = MediaHeader.decode(concatenateChunks(part.data.chunks));
console.log('Media Header:', mediaHeader);
}
function handleMedia(part: Part) {
const headerId = part.data.getUint8(0);
console.log(`Media Part (Associated Header ID: ${headerId}):`, part.data.split(1).remainingBuffer.getLength(), 'bytes');
}
function handleMediaEnd(part: Part) {
const headerId = part.data.getUint8(0);
console.log(`Media End Part (Associated Header ID: ${headerId}):`, part.data.split(1).remainingBuffer.getLength(), 'bytes');
}
const umpPartHandlers = new Map void>([
[ UMPPartId.MEDIA_HEADER, handleMediaHeader ],
[ UMPPartId.MEDIA, handleMedia ],
[ UMPPartId.MEDIA_END, handleMediaEnd ]
]);
const buffer = mockUmpData();
const reader = new UmpReader(buffer);
reader.read((part) => {
const handler = umpPartHandlers.get(part.type);
if (handler) {
handler(part);
} else {
console.warn(`No handler for part type: ${part.type}`);
}
});
/**
* Generates a mock UMP data buffer containing a MEDIA_HEADER, and respective MEDIA and MEDIA_END parts.
* This group represents a single audio segment, which is what you would typically see
* in a real UMP stream.
*/
function mockUmpData(): CompositeBuffer {
const buffer = new CompositeBuffer();
const writer = new UmpWriter(buffer);
const audioHeaderId = 0;
const partsToWrite: [UMPPartId, Uint8Array][] = [
[
UMPPartId.MEDIA_HEADER,
MediaHeader.encode({
headerId: audioHeaderId,
videoId: "sOa4VVlI9tE",
itag: 141,
lmt: 1645502668395260,
xtags: "",
startRange: 5463800,
isInitSeg: false,
sequenceNumber: 0,
durationMs: 0,
formatId: {
itag: 141,
lastModified: 1645502668395260,
xtags: ""
},
contentLength: 963966,
}).finish()
],
[ UMPPartId.MEDIA, new Uint8Array([ audioHeaderId, ...new Uint8Array(827609).fill(0) ]) ],
[ UMPPartId.MEDIA, new Uint8Array([ audioHeaderId, ...new Uint8Array(136357).fill(0) ]) ],
[ UMPPartId.MEDIA_END, new Uint8Array([ audioHeaderId ]) ]
];
for (const [type, data] of partsToWrite) {
writer.write(type, data);
}
return buffer;
}
```
Expected output:
```
Media Header: { ... }
Media Part (Associated Header ID: 0): 827609 bytes
Media Part (Associated Header ID: 0): 136357 bytes
Media End Part (Associated Header ID: 0): 0 bytes
```
## License
Distributed under the [MIT](./LICENSE) License.