# WebM

> Encode VP9 video and optional Opus audio into a WebM file.

Use `webm_vp9` to create a VP9 video file. When the Source has audio, Chunkify encodes it as Opus at 48 kHz. Set `disable_audio: true` for video only.

Default video settings are CRF 24, `quality: realtime`, `cpu_used: "5"`, and `pixfmt: yuv420p`. The `cpu_used` option controls VP9 encoding effort and its speed-quality tradeoff.

## Create a WebM transcode

The example sets a height of 720 pixels and CRF 24. Width follows the Source aspect ratio.

Run these examples on your server after [setting up your SDK and Source](/docs/transcoding/quickstart#before-you-begin). Replace the token and Source ID.

These examples save the file in your Project's output storage. Set `storage.path` to the filename you want to use.

<ignore>
SDK publication check: drafted from api/openapi.json and existing SDK conventions. Add Transcodings models, create/retrieve/list/cancel/delete mappings, pagination and data unwrapping to the owning SDK generator configuration. Verify generated method names and Go union/format/storage types in TypeScript, Python, PHP and Go before publication.
</ignore>

<codegroup>
<codeblock lang="TypeScript">
```typescript
import Chunkify from '@chunkify/chunkify';

async function main() {
    const client = new Chunkify({
        projectAccessToken: 'My Project Access Token',
    });

    const transcoding = await client.transcodings.create({
        source_id: 'src_2G6MJiNz71bHQGNzGwKx5cJwPFS',
        format: {
            id: "webm_vp9",
            height: 720,
            crf: 24,
        },
        storage: {
            path: 'exports/video-720p.webm',
        },
    });

    console.log(transcoding.id, transcoding.status);
}

main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
});
```
</codeblock>
<codeblock lang="Python">
```python
from chunkify import Chunkify

client = Chunkify(
    project_access_token="My Project Access Token",
)

transcoding = client.transcodings.create(
    source_id="src_2G6MJiNz71bHQGNzGwKx5cJwPFS",
    format={
        "id": "webm_vp9",
        "height": 720,
        "crf": 24,
    },
    storage={
        "path": "exports/video-720p.webm",
    },
)

print(transcoding.id, transcoding.status)
```
</codeblock>
<codeblock lang="PHP">
```php
<?php

use Chunkify\Client;

require_once __DIR__ . '/vendor/autoload.php';

$client = new Client(
    projectAccessToken: 'My Project Access Token',
);

$transcoding = $client->transcodings->create(
    sourceID: 'src_2G6MJiNz71bHQGNzGwKx5cJwPFS',
    format: [
        'id' => 'webm_vp9',
        'height' => 720,
        'crf' => 24,
    ],
    storage: [
        'path' => 'exports/video-720p.webm',
    ],
);

var_dump($transcoding->id, $transcoding->status);
```
</codeblock>
<codeblock lang="Go">
```go
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/chunkifydev/chunkify-go"
	"github.com/chunkifydev/chunkify-go/option"
)

func main() {
	client := chunkify.NewClient(
		option.WithProjectAccessToken("My Project Access Token"),
	)

	transcoding, err := client.Transcodings.New(
		context.Background(),
		chunkify.TranscodingNewParams{
			SourceID: "src_2G6MJiNz71bHQGNzGwKx5cJwPFS",
			Format: chunkify.TranscodingNewParamsFormatUnion{
				OfWebmVp9: &chunkify.TranscodingWebmVp9Param{
					Height: chunkify.Int(720),
					Crf:    chunkify.Int(24),
				},
			},
			Storage: chunkify.TranscodingNewParamsStorage{
				Path: chunkify.String("exports/video-720p.webm"),
			},
		},
	)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(transcoding.ID, transcoding.Status)
}
```
</codeblock>
</codegroup>

## Rate control

Set `per_title: true` to select a bitrate from the video content, or supply `video_bitrate` for an explicit target. Do not combine either with a manual CRF.

VP9 `maxrate` and `bufsize` require a target `video_bitrate`. `minrate` is supported only when it equals both `video_bitrate` and `maxrate`, selecting constant bitrate encoding.

## Encoding parameters

<openapi-schema schema="#/components/schemas/TranscodingWebmVp9"></openapi-schema>
