From 4ef8c558d246f2ac0dd4e7ab18eebf28880514ab Mon Sep 17 00:00:00 2001 From: szekelyzol Date: Tue, 5 Sep 2023 22:43:34 +0000 Subject: [PATCH] Update ingestion and transcoding section pages --- vod/encoding-transcoding.md | 49 +- vod/navigation.yaml | 16 +- vod/progressive-upload.md | 360 +++++++++++++- vod/upload-a-video-regular-upload.md | 712 ++++++++++----------------- vod/upload-from-source.md | 354 +++++++++++++ vod/upload-your-first-video.md | 2 +- vod/using-tokens.md | 10 +- vod/using-video-metadata.md | 12 - vod/video-upload.md | 1 - 9 files changed, 1054 insertions(+), 462 deletions(-) create mode 100644 vod/upload-from-source.md delete mode 100644 vod/using-video-metadata.md delete mode 100644 vod/video-upload.md diff --git a/vod/encoding-transcoding.md b/vod/encoding-transcoding.md index ad3499c7..1a97ebe5 100644 --- a/vod/encoding-transcoding.md +++ b/vod/encoding-transcoding.md @@ -1 +1,48 @@ -what-is-api-video.md \ No newline at end of file +--- +title: "Encoding and transcoding" +slug: "encoding-transcoding" +metadata: + title: "Encoding and transcoding • api.video Documentation" + description: "This guide explains what video encoding and transcoding means and how api.video enables you to provide your users high quality videos via encoding and transcoding." +--- + +## Encoding + +The term encoding is used to describe the process of converting content into a different form. In the context of video - encoding technically only happens when the video is being recorded, and taken from the camera's raw format and saved into a [codec](https://api.video/what-is/codec/). Any further manipulations of the video file (say changing the format, or changing compression values) is transcoding. But, in practice, these two terms are used interchangeably to describe the process of converting a video file from one format to another. + +### Why encode a video? +Video files are inherently large, so using a codec to compress the video ensures that the file will be much smaller. As codecs get better at compression, we are able to transmit higher quality video for the same amount of data. For that reason, there is a lot of research into new codecs. + +There are other considerations to undertake when choosing how to encode your video. The [H264](https://api.video/what-is/h-264/), while older and not the best compression, does support the highest browser support - making it a common encoding choice. Newer codecs like [H265](https://api.video/what-is/h-265/), VP9, and AVIF have better compression, but suffer slightly in the realm of browser support for playback. + +### Encoding settings +When using a tool like FFMPEG, you can set the video quality. This determines how much compression there will be/how good the video will look. Higher compression leads to smaller files, but also higher [loss](https://api.video/what-is/lossy-compression/). FFMPEG uses the Constant Rate Factor for encoding quality (values of 0 are lossless, 51 is high compression.) The default value for CRF is 23, and generally creates a video that offers a high compression/quality ratio: + +``` +ffmpeg -i input -c:v libx264 -crf 23 output.mp4 +``` + +### Encoding at api.video + +Every video uploaded to api.video is encoded/transcoded into an H264 MP4 and an HLS video stream with up to 6 different sizes (240p, 360p, 480p, 720p, 1080p, 2160p). This ensures that video playback can occur on any device (the MP4), and along with our video player (or any other video player that supports HLS), your video can stream to the web quickly and efficiently. + +## Transcoding + +Transcoding is the process of taking already encoded (or transcoded) content, decompressing it and then using different codecs to alter or recompress it. It's labor intensive because you are taking every part of your video and audio and recompressing it. During this process, depending on what codecs you use, you may lose data. + +### What types of transcoding are there? + +There are three types of transcoding you will encounter: + +- Lossy-to-lossy - This is where you take a codec that is lossy and transcode to another format that uses a lossy codec. You will lose lots of data during this process, and transcoding will lower the quality of your video. +- Lossless-to-lossy - This is where you take a codec that preserves every detail of a video and transfer it to one that loses data. The trade off results in something useful like faster decompression for playback, or a smaller file. +- Lossy-to-lossless - You cannot regain lost quality, so when transcoding in this situation, you retain all the data that was in the lossy compression without further degradation of the file. + +### What are the goals of transcoding? +The goals of transcoding are dependent upon your use case. The main reason to transcode video is because you want to use it in a new scenario with a codec that's optimized for that new scenario. For example, say you want to edit a video. You would probably want a codec that's good quality, but which lets you easily move backwards and forwards through the video so you can quickly find the parts of the video you want to clip and edit. A great example of a codec for this purpose would be ProRes. This codec doesn't work for playback with a lot of devices though. So after you're done editing, you would want to transcode to another codec that works for playback. + +Other scenarios might be something like wanting to store a video for later use. When you store a video, if it's for a project, you might want to store the highest quality possible. Then when you get the video out later to edit again or use in a project, it's got as much information available as possible. Or, maybe you're storing a video just for reference purposes and you don't have a lot of space. Then you might want a codec that compresses efficiently but the video quality is lower. That would be enough for reference later. + +### Transcoding and api.video + +api.video transcodes your video to HLS for fast, high quality playback across the internet. If you're interested in learning more about transcoding, check out our article [Encoding and Transcoding - What's the Difference?](https://api.video/blog/video-trends/what-is-the-difference-between-encoding-and-transcoding/). \ No newline at end of file diff --git a/vod/navigation.yaml b/vod/navigation.yaml index 8efe671d..4f09a683 100644 --- a/vod/navigation.yaml +++ b/vod/navigation.yaml @@ -28,12 +28,22 @@ - heading: Video ingestion & transcoding items: + - label: Encoding and transcoding + href: /vod/encoding-transcoding.md - label: Regular video upload href: /vod/upload-a-video-regular-upload.md - - label: Progressive upload + - label: Progressive video upload href: /vod/progressive-upload.md - - label: Encoding and transcoding - href: /vod/encoding-transcoding.md + - label: Upload video from source + href: /vod/upload-from-source.md + - label: Using upload tokens + href: /vod/using-tokens.md + collapsed: true + items: + - label: Create and manage delegated upload tokens + href: /vod/create-and-manage-tokens-for-delegated-uploads.md + - label: Upload a video with a delegated token + href: /vod/upload-a-video-with-a-delegated-token.md - heading: Video management items: diff --git a/vod/progressive-upload.md b/vod/progressive-upload.md index ad3499c7..45a5a438 100644 --- a/vod/progressive-upload.md +++ b/vod/progressive-upload.md @@ -1 +1,359 @@ -what-is-api-video.md \ No newline at end of file +--- +title: "Progressive video upload" +--- +Progressive video upload +============================= + +api.video provides different ways to upload your videos. There are two ways to upload with tokens, and then there are two ways to upload depending on whether your video is over 200MB or under. This guide walks through how to do progressive video upload. Options covered in this guide include: + +- Progressive upload for a video that's 200MiB or more +- Progressive upload for a video that's 200MiB or more using `byte` range in the `Content-Range` header + +{% capture content %} +Megabyte (MB) and Mebibyte (MiB) are both used to measure units of information on computer storage. 1 MB is 1000Kb (kilobytes), and 1 MiB is 1048.576Kb. api.video uses MiB. +{% endcapture %} +{% include "_partials/callout.html" kind: "info", content: content %} + +## API documentation + +- [Create a video](/reference/api/Videos#create-a-video-object) +- [Upload a video](/reference/api/Videos#upload-a-video) + +## Create an account + +Before you can start uploading your first video, you need to [create an api.video account](https://dashboard.api.video/register). + +Once you are logged in to the Dashboard, select the environment of your choice (sandbox or production) and copy your API key. + +## Choose an API client + +The clients offered by api.video include: + +- [NodeJS](/sdks/api-clients/apivideo-nodejs-client.md) +- [Python](/sdks/api-clients/apivideo-python-client.md) +- [PHP](/sdks/api-clients/apivideo-php-client.md) +- [Go](/sdks/api-clients/apivideo-go-client.md) +- [C#](/sdks/api-clients/apivideo-csharp-client.md) +- [Java](/sdks/api-clients/apivideo-java-client.md) +- [iOS](/sdks/api-clients/ios-api-client.md) +- [Android](/sdks/api-clients/android-api-client.md) + +## Install + +To install your selected client, do the following: + +{% capture samples %} + +```go +go get github.com/apivideo/api.video-go-client +``` +```php +composer require api-video/php-api-client +``` +```javascript +npm install @api.video/nodejs-client --save + +...or with yarn: + +yarn add @api.video/nodejs-client +``` +```python +pip install api.video +``` +```csharp +Using Nuget + +Install-Package ApiVideo +``` + +{% endcapture %} +{% include "_partials/code-tabs.html" content: samples %} + +## Progressive upload in file chunks + +When the video file you want to upload is too large to send in one request, you need to do a progressive upload. To upload the entire video, you must broken into chunks, and send each chunk in separate requests. The smallest chunk size allowed is **5 MiB**. + +- When you do a progressive upload using one of the api.video clients, you must indicate when you send the last part. +- If you implement this functionality without an api.video client, you do not need to indicate the last part of the progressive upload. api.video can track the chunk numbers based on your header which indicates `Content-Range`, for example : part 3/3, according to the number of chunks you sent. + +{% capture samples %} + +```curl +curl --request POST \ + --url https://ws.api.video/videos \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI1NDk1NjAuMDE5ODA0LCJuYmYiOjE2NDI1NDk1NjAuMDE5ODA0LCJleHAiOjE2NDI1NTMxNjAuMDE5ODA0LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.jjr4YADGbe62RmBBxJXLy1D61Mtfry_dq9nbriBXgkPrdlBJ8ZRP50CyW3AsGD7wSuKp2mXxEYSzj64zelT1IGOwg6KG4Gz9BZ9YWs0GAHKUIdgqn1gzITX5aQljIXx1fquXbawd-axBTi4icmaUjgXjfnyIcWOgHd2D8A3kpKiqiMmluh58JdnwPnH0OyVk0Rk824P0PI6SxfiTHfkCglPL6ixf9OgokMLPoVrsxH5C0xt3Z7lf5TJ0F78-JY-yTKvyaTTIfI6CFOMNaZUlMtgQwq8X93_2FA65Ntw3hdDML8gFKkLUxnBAtZMo9WAjUd30G4OcYasmlkc4Q_JSNw' \ + --header 'Content-Type: application/json' \ + --data ' +{ + "public": true, + "panoramic": false, + "mp4Support": true, + "title": "HelloWorld" +} +' + +# Retrieve the access_token from the response, then include in your next request. + +curl --request POST \ + --url https://ws.api.video/videos//source \ + --header 'Accept: application/json' \ + --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI4MjQzMTkuMDk2NjY1LCJuYmYiOjE2NDI4MjQzMTkuMDk2NjY1LCJleHAiOjE2NDI4Mjc5MTkuMDk2NjY1LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.rfchf3btbMTzSukcwhUS0u4fNY4Q3g1JpoMeIz_Dls1ADmqDdKw7yBOE893C7cagb0lpuvUJvhuhgusLStsJ4nqzTveDeM2oPBQBNJjzwaJZNrImTPD4mif7Tzgxvn1_jQJA5L4gQhjd7frCIJW1yAwywrtiDPbxiWNp8fVl7r_QILjZZfslxy-kblPrHJ20Zix9VURqkGIORY5G_457nHSV9Atks1sUlt49E8b_g3jORja3MnznXBS0-0dksz2K62-QMe1_dk78V9JwbLeydqcr15M1jDLA3H6qFGI7GTsTDdZ5jKLhg5OR6yeSHFysqr3kOteTqAGdp3JuTrpZIA' \ + --header 'Content-Range: part%201%2F3' \ + --header 'Content-Type: multipart/form-data' + +# You would send each part until the last part is sent. In order to do this with a cURL request, you must break your video into chunks ahead of time. +``` +```go +package main + +import ( + "context" + "fmt" + "os" + apivideosdk "github.com/apivideo/api.video-go-client" +) + +func main() { + client := apivideosdk.ClientBuilder("YOUR_API_TOKEN").Build() + // if you rather like to use the sandbox environment: + // client := apivideosdk.SandboxClientBuilder("YOU_SANDBOX_API_TOKEN").Build() + + videoId := "vi4k0jvEUuaTdRAEjQ4Jfrgz" // string | Enter the videoId you want to use to upload your video. + + part1, err := os.Open("10m.mp4.part.a") + part2, err := os.Open("10m.mp4.part.b") + part3, err := os.Open("10m.mp4.part.c") + + stream = client.Videos.CreateUploadStream(videoId) + _, err = stream.UploadPartFile(part1) + _, err = stream.UploadPartFile(part2) + res, err := stream.UploadLastPartFile(part3) + + err = part1.Close() + err = part2.Close() + err = part3.Close() +``` +```php +videos()->create((new VideoCreationPayload())->setTitle('Uploaded video')); +$client->videos()->upload($myVideo->getVideoId(), new SplFileObject(__DIR__ . '/../../../tests/resources/558k.mp4')); + +// create a new video & upload a video file using progressive upload (the file is uploaded by parts) +$myVideo2 = $client->videos()->create((new VideoCreationPayload())->setTitle('Uploaded video (progressive upload)')); + +$progressiveSession = $client->videos()->createUploadProgressiveSession($myVideo2->getVideoId()); + +$progressiveSession->uploadPart(new SplFileObject(__DIR__ . '/../../../tests/resources/10m.mp4.part.a')); +$progressiveSession->uploadPart(new SplFileObject(__DIR__ . '/../../../tests/resources/10m.mp4.part.b')); + +$progressiveSession->uploadLastPart(new SplFileObject(__DIR__ . '/../../../tests/resources/10m.mp4.part.c')); +``` +```javascript +const ApiVideoClient = require('@api.video/nodejs-client'); + +(async () => { +try { + + const client = new ApiVideoClient({ apiKey: "YOUR_API_TOKEN" }); + + const videoId = 'vi4k0jvEUuaTdRAEjQ4Jfrgz'; // Enter the videoId you want to use to upload your video. + + const uploadSession = client.createUploadProgressiveSession(videoId); + + await uploadSession.uploadPart('test/data/10m.mp4.part.a'); + await uploadSession.uploadPart('test/data/10m.mp4.part.b'); + const res = await uploadSession.uploadLastPart('test/data/10m.mp4.part.c'); // Video + + console.log(result); + } catch (e) { + console.error(e); + } +})(); +``` +```python +import os +import apivideo +from apivideo.apis import VideosApi +from apivideo.exceptions import ApiAuthException + +api_key = "your API key here" + +## Set up the authenticated client +client = apivideo.AuthenticatedApiClient(api_key) + +## if you rather like to use the sandbox environment: +## client = apivideo.AuthenticatedApiClient(api_key, production=False) +client.connect() + +videos_api = VideosApi(client) + +video_create_payload = { + "title": "Progressive Test", + "description": "test", + "public": False, + "tags": ["nature"] +} +## Create the container for your video and print the response +response = videos_api.create(video_create_payload) +print("Video Container", response) + +## Retrieve the video ID, you can upload once to a video ID +video_id = response["video_id"] + +session = videos_api.create_upload_progressive_session(video_id) + +CHUNK_SIZE = 6000000 + +## This is our chunk reader. This is what gets the next chunk of data ready to send. +def read_in_chunks(file_object, CHUNK_SIZE): + while True: + data = file_object.read(CHUNK_SIZE) + if not data: + break + yield data + +## Upload your file by breaking it into chunks and sending each piece +def upload(file): + content_name = str(file) + content_path = os.path.abspath(file) + + f = open(content_path, "rb") + index = 0 + offset = 0 + part_num = 1 + headers = {} + + for chunk in read_in_chunks(f, CHUNK_SIZE): + offset = index + len(chunk) + index = offset + + with open('chunk.part.' + str(part_num), 'wb') as chunk_file: + chunk_file.write(chunk) + chunk_file.close() + + with open('chunk.part.' + str(part_num), 'rb') as chunk_file: + try: + if len(chunk) == CHUNK_SIZE: + session.uploadPart(chunk_file) + elif len(chunk) < CHUNK_SIZE: + print(session.uploadLastPart(chunk_file)) + chunk_file.close() + except Exception as e: + print(e) + + os.remove('chunk.part.' + str(part_num)) + part_num += 1 + +upload('VIDEO_FILE.mp4') +``` + +{% endcapture %} +{% include "_partials/code-tabs.html" content: samples %} + + +## Progressive upload with byte range in the content-range header + +A slightly more complicated way to upload a video that's 200 MiB or larger is to use `bytes` in the `content-range` header. This method requires that you define the exact byte ranges correctly, otherwise the entire upload to fail. When done correctly, your header will look like this: + +``` +Content-Range: bytes 0-5242879 +``` + +And then continue from there. By default, the api.video clients handle uploads for you using this method. If you want to try it yourself without the client, the sample will look like this in cURL: + +{% capture samples %} + +```curl +curl -X POST \ + https://sandbox.api.video/auth/api-key \ + -H 'Content-Type: application/json' \ + -d '{"apiKey": "your_api_key"}' + +# Retrieve the access_token from the response, then include in your next request. + +curl -X POST https://sandbox.api.video/videos \ + -H 'Content-Type: application/json' \ + -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFiYjcxNmNiY2ZiNmY4MDc2OWEzZmQ1MjlhMjZiZWRkY2EwMzhlYzA3NDk5M2ZiMTA0YjhiZGMwOTI5MzgxN2M3NmNkNzI4ZDIzOGMzZmNlIn0.eyJhdWQiOiJsaWJjYXN0IiwianRpIjoiYWJiNzE2Y2JjZmI2ZjgwNzY5YTNmZDUyOWEyNmJlZGRjYTAzOGVjMDc0OTkzZmIxMDRiOGJkYzA5MjkzODE3Yzc2Y2Q3MjhkMjM4YzNmY2UiLCJpYXQiOjE1MjY1NDgzMDEsIm5iZiI6MTUyNjU0ODMwMSwiZXhwIjoxNTI2NTUxOTAxLCJzdWIiOiJ1c01vbml0b3IiLCJzY29wZXMiOlsibW9uaXRvci5saWJjYXN0LmNvbSJdLCJjb250ZXh0Ijp7InVzZXIiOiJ1c01vbml0b3IiLCJwcm9qZWN0IjoicHJNb25pdG9yIiwibWVtYmVyIjoibWVNb25pdG9yIn19.jWHC18iEur69FzD5dm78wAwNzh2cPKTRvKuspyQNQKPvhEbYa2v4XhqVNh0TTw8JeNxBtcePBTMHl4S9nWsw7pW4KD8zbqzUjCZNYlaYDpu8vu_tmWVO2JccglJIjuQEaiTbkUsfLdgtsb_9DJ3frk1-WgAKuzu0HewhcGb80xivdJPqNYA6I1Ig8GOief9LTUNNJoqqZn1A1-UiGRTXDag7_yODuxzpMFaAzbaisfK0gYti-PnjyHGWhpGwRplMKPPJk6rSAp1d9TWWXVgg-bNqUzz4_sr33ICJTx7_qZzfamMqk5PDZbHOwpIj8L2DBfo3isvt6QliWmgFEOuvog' \ + -d '{ + "title":"This is a title", + "description":"My video description", + "source":"https://example.com/myVideo.mp4" + }' + +# Split your video into chunks, if you're on a mac you can use this command + +split -b 100m source.mp4.mp4 file_chunk_ + +# Split your video into chunks, if you're using Linux you can use this command + +/path/to/source.mp4` is a 289MB (`281905832 B`) file . + +split --bytes=100M source.mp4 file_chunk_ + +# You'll need to send a cURL request for each chunk, with the proper Content-Range header + +curl https://sandbox.api.video/videos/vitq4gOj8GyDT9kyxPQoyNJl/source \ + -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFiYjcxNmNiY2ZiNmY4MDc2OWEzZmQ1MjlhMjZiZWRkY2EwMzhlYzA3NDk5M2ZiMTA0YjhiZGMwOTI5MzgxN2M3NmNkNzI4ZDIzOGMzZmNlIn0.eyJhdWQiOiJsaWJjYXN0IiwianRpIjoiYWJiNzE2Y2JjZmI2ZjgwNzY5YTNmZDUyOWEyNmJlZGRjYTAzOGVjMDc0OTkzZmIxMDRiOGJkYzA5MjkzODE3Yzc2Y2Q3MjhkMjM4YzNmY2UiLCJpYXQiOjE1MjY1NDgzMDEsIm5iZiI6MTUyNjU0ODMwMSwiZXhwIjoxNTI2NTUxOTAxLCJzdWIiOiJ1c01vbml0b3IiLCJzY29wZXMiOlsibW9uaXRvci5saWJjYXN0LmNvbSJdLCJjb250ZXh0Ijp7InVzZXIiOiJ1c01vbml0b3IiLCJwcm9qZWN0IjoicHJNb25pdG9yIiwibWVtYmVyIjoibWVNb25pdG9yIn19.jWHC18iEur69FzD5dm78wAwNzh2cPKTRvKuspyQNQKPvhEbYa2v4XhqVNh0TTw8JeNxBtcePBTMHl4S9nWsw7pW4KD8zbqzUjCZNYlaYDpu8vu_tmWVO2JccglJIjuQEaiTbkUsfLdgtsb_9DJ3frk1-WgAKuzu0HewhcGb80xivdJPqNYA6I1Ig8GOief9LTUNNJoqqZn1A1-UiGRTXDag7_yODuxzpMFaAzbaisfK0gYti-PnjyHGWhpGwRplMKPPJk6rSAp1d9TWWXVgg-bNqUzz4_sr33ICJTx7_qZzfamMqk5PDZbHOwpIj8L2DBfo3isvt6QliWmgFEOuvog' \ + -H 'Content-Range: bytes 0-104857599/281905832' \ + -F file=@/path/to/file_chunk_aa + +curl https://sandbox.api.video/videos/vitq4gOj8GyDT9kyxPQoyNJl/source \ + -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFiYjcxNmNiY2ZiNmY4MDc2OWEzZmQ1MjlhMjZiZWRkY2EwMzhlYzA3NDk5M2ZiMTA0YjhiZGMwOTI5MzgxN2M3NmNkNzI4ZDIzOGMzZmNlIn0.eyJhdWQiOiJsaWJjYXN0IiwianRpIjoiYWJiNzE2Y2JjZmI2ZjgwNzY5YTNmZDUyOWEyNmJlZGRjYTAzOGVjMDc0OTkzZmIxMDRiOGJkYzA5MjkzODE3Yzc2Y2Q3MjhkMjM4YzNmY2UiLCJpYXQiOjE1MjY1NDgzMDEsIm5iZiI6MTUyNjU0ODMwMSwiZXhwIjoxNTI2NTUxOTAxLCJzdWIiOiJ1c01vbml0b3IiLCJzY29wZXMiOlsibW9uaXRvci5saWJjYXN0LmNvbSJdLCJjb250ZXh0Ijp7InVzZXIiOiJ1c01vbml0b3IiLCJwcm9qZWN0IjoicHJNb25pdG9yIiwibWVtYmVyIjoibWVNb25pdG9yIn19.jWHC18iEur69FzD5dm78wAwNzh2cPKTRvKuspyQNQKPvhEbYa2v4XhqVNh0TTw8JeNxBtcePBTMHl4S9nWsw7pW4KD8zbqzUjCZNYlaYDpu8vu_tmWVO2JccglJIjuQEaiTbkUsfLdgtsb_9DJ3frk1-WgAKuzu0HewhcGb80xivdJPqNYA6I1Ig8GOief9LTUNNJoqqZn1A1-UiGRTXDag7_yODuxzpMFaAzbaisfK0gYti-PnjyHGWhpGwRplMKPPJk6rSAp1d9TWWXVgg-bNqUzz4_sr33ICJTx7_qZzfamMqk5PDZbHOwpIj8L2DBfo3isvt6QliWmgFEOuvog' \ + -H 'Content-Range: bytes 104857600-209715199/281905832' \ + -F file=@/path/to/file_chunk_ab + +curl https://sandbox.api.video/videos/vitq4gOj8GyDT9kyxPQoyNJl/source \ + -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFiYjcxNmNiY2ZiNmY4MDc2OWEzZmQ1MjlhMjZiZWRkY2EwMzhlYzA3NDk5M2ZiMTA0YjhiZGMwOTI5MzgxN2M3NmNkNzI4ZDIzOGMzZmNlIn0.eyJhdWQiOiJsaWJjYXN0IiwianRpIjoiYWJiNzE2Y2JjZmI2ZjgwNzY5YTNmZDUyOWEyNmJlZGRjYTAzOGVjMDc0OTkzZmIxMDRiOGJkYzA5MjkzODE3Yzc2Y2Q3MjhkMjM4YzNmY2UiLCJpYXQiOjE1MjY1NDgzMDEsIm5iZiI6MTUyNjU0ODMwMSwiZXhwIjoxNTI2NTUxOTAxLCJzdWIiOiJ1c01vbml0b3IiLCJzY29wZXMiOlsibW9uaXRvci5saWJjYXN0LmNvbSJdLCJjb250ZXh0Ijp7InVzZXIiOiJ1c01vbml0b3IiLCJwcm9qZWN0IjoicHJNb25pdG9yIiwibWVtYmVyIjoibWVNb25pdG9yIn19.jWHC18iEur69FzD5dm78wAwNzh2cPKTRvKuspyQNQKPvhEbYa2v4XhqVNh0TTw8JeNxBtcePBTMHl4S9nWsw7pW4KD8zbqzUjCZNYlaYDpu8vu_tmWVO2JccglJIjuQEaiTbkUsfLdgtsb_9DJ3frk1-WgAKuzu0HewhcGb80xivdJPqNYA6I1Ig8GOief9LTUNNJoqqZn1A1-UiGRTXDag7_yODuxzpMFaAzbaisfK0gYti-PnjyHGWhpGwRplMKPPJk6rSAp1d9TWWXVgg-bNqUzz4_sr33ICJTx7_qZzfamMqk5PDZbHOwpIj8L2DBfo3isvt6QliWmgFEOuvog' \ + -H 'Content-Range: bytes 209715200-281905831/281905832' \ + -F file=@/path/to/file_chunk_ac + +``` + +{% endcapture %} +{% include "_partials/code-tabs.html" content: samples %} + + +{% capture content %} +All api.video clients automatically use the `Content-Range: bytes` method to upload big videos for you. You don't have to set it up yourself if you use a client! +{% endcapture %} +{% include "_partials/callout.html" kind: "info", content: content %} + +## Resources + +Check out api.video's blog content on video upload: + +- [Video upload with cURL](https://api.video/blog/tutorials/video-upload-tutorial) - **cURL** + +- [Video upload (large videos) with cURL](https://api.video/blog/tutorials/video-upload-tutorial-large-videos) **cURL** + +- [Upload many files at once with HTML and JavaScript](https://api.video/blog/tutorials/upload-many-files-at-once-with-html-and-javascript) - **JavaScript** Upload many files at once using an HTML form and JavaScript without the api.video client. + +- [Upload a video with Laravel](https://api.video/blog/tutorials/upload-a-video-with-laravel) - **PHP** Create a form that uploads a video to api.video using Laravel. + +- [Upload a video with the api.video PHP client](https://api.video/blog/tutorials/upload-a-video-with-the-api-video-php-client) - **PHP** A tutorial about how to upload a video with the PHP API client, this will work for large or small files and uses the Content-Range header method. + +- [Progressively upload large video files without compromising speed](https://api.video/blog/tutorials/progressively-upload-large-video-files-without-compromising-on-speed) - **Python** A tutorial that walks you through using progressive uploads without using an API client. + +- [Upload a big video file using Python](https://api.video/blog/tutorials/upload-a-big-video-file-using-python) - **Python** Learn how to break a large video file into chunks and upload each chunk using Python. + +- [Upload a video from your computer with the api.video API](https://api.video/blog/tutorials/upload-a-video-from-your-computer-with-the-api-video-api-python) - **Python** Upload a video from your computer using Python. + +- [Upload a video to api.video using a public URL](https://api.video/blog/tutorials/upload-a-video-with-the-api-video-api-using-a-public-url-python) - **Python** Learn how to upload a video from a public mp4 link. + +- [Upload a video with the api.video Python Client](https://api.video/blog/tutorials/upload-a-video-with-the-api-video-python-client) - **Python** Upload a video of any size using api.video's Python client. + +- [Use Flask with Dropzone.js to upload videos under 200 MiB (no client)](https://api.video/blog/tutorials/use-flask-with-dropzone-js-to-upload-videos-under-128mb-no-client) - **Python** Learn how to do an upload for files under 200 MiB without using an api.video client. diff --git a/vod/upload-a-video-regular-upload.md b/vod/upload-a-video-regular-upload.md index 14816881..18afdaae 100644 --- a/vod/upload-a-video-regular-upload.md +++ b/vod/upload-a-video-regular-upload.md @@ -1,21 +1,19 @@ --- -title: "Upload a video - advanced guide" +title: "Regular video upload" --- -Upload A Video Regular Upload +Regular video upload ============================= -api.video provides different ways to upload your videos. There are two ways to upload with tokens, and then there are two ways to upload depending on whether your video is over 200MB or under. This guide walks through how to do all the different kinds of regular uploads available to you. Options covered in this guide include: +api.video provides different ways to upload your videos. There are two ways to upload with tokens, and then there are two ways to upload depending on whether your video is over 200MiB or under. This guide walks through how to do regular video upload for a video under 200MiB in size. -- Regular upload for a video under 200MiB in size -- Regular upload for a video that's 200MiB or more using a progressive upload -- Regular upload for a video that's 200MiB or more using byte range in the Content-Range header +Check out the guide on [Progressive upload](/vod/progressive-upload.md) to understand how to upload videos larger than 200MiB in size. {% capture content %} Megabyte (MB) and Mebibyte (MiB) are both used to measure units of information on computer storage. 1 MB is 1000Kb (kilobytes), and 1 MiB is 1048.576Kb. api.video uses MiB. {% endcapture %} {% include "_partials/callout.html" kind: "info", content: content %} -## Associated API reference documentation +## API documentation - [Create a video](/reference/api/Videos#create-a-video-object) - [Upload a video](/reference/api/Videos#upload-a-video) @@ -25,28 +23,37 @@ Megabyte (MB) and Mebibyte (MiB) are both used to measure units of information o This section gives you an overview of your upload options. This guide walks through regular uploads but describes all the available choices here. {% capture content %} -If you want to learn about delegated uploads, which are useful for creating private videos, or allowing your viewers to upload content themselves, or even just making it easier for you to do uploads, please see the [Create and manage tokens for delegated uploads](/get-started/create-and-manage-tokens-for-delegated-uploads) guide and the [Upload a video with a delegated token](/get-started/upload-a-video-with-a-delegated-token) guide. +If you want to learn about delegated uploads, which are useful for creating private videos, or allowing your viewers to upload content themselves, or even just making it easier for you to do uploads, please see the [Create and manage tokens for delegated uploads](/vod/create-and-manage-tokens-for-delegated-uploads) guide and the [Upload a video with a delegated token](/vod/upload-a-video-with-a-delegated-token) guide. {% endcapture %} {% include "_partials/callout.html" kind: "info", content: content %} The two token-based upload methods are: -- Regular upload - you use an access token you retrieved when you authenticate to do a two-step process where you create a video container with metadata, retrieve the video ID, and use that to upload your video into the container. +- Regular upload - you use an access token you retrieved when you authenticate to do a two-step process where you create a video object with metadata, retrieve the video ID, and use that to upload your video into the object. - Delegated upload - you create a token and use the token to upload your video in one step. You can change the metadata later on. -There are two types of upload depending on whether your video is over 200MB or under. You can use either a regular or delegated upload for a video under 200 MB. If the video is over 200MB, you can do a progressive upload, where you break a video into chunks and then upload the pieces using parts in the header. You can also use bytes in the header, which is a bit more complicated. If you use one of the clients, big uploads are handled for you using the bytes method. You can also use the progressive upload method if you wish, though the steps require a bit more effort. +There are two types of upload depending on whether your video is over 200MiB or under. You can use either a regular or delegated upload for a video under 200MiB. If your video is over 200MiB, you can do a [progressive upload](/vod/progressive-upload.md), where you break a video into chunks and then upload the pieces using parts in the header. You can also use bytes in the header, which is a bit more complicated. If you use one of the clients, big uploads are handled for you using the bytes method. You can also use the progressive upload method if you wish, though the steps require a bit more effort. -## Choose an api.video client +## Create an account + +Before you can start uploading your first video, you need to [create an api.video account](https://dashboard.api.video/register). + +Once you are logged in to the Dashboard, select the environment of your choice (sandbox or production) and copy your API key. + +## Choose an API client The clients offered by api.video include: -- [Go](https://github.com/apivideo/api.video-go-client) -- [PHP](https://github.com/apivideo/api.video-php-client) -- [JavaScript ](https://github.com/apivideo/api.video-nodejs-client) -- [Python](https://github.com/apivideo/api.video-python-client) -- [C#](https://github.com/apivideo/api.video-csharp-client) +- [NodeJS](/sdks/api-clients/apivideo-nodejs-client.md) +- [Python](/sdks/api-clients/apivideo-python-client.md) +- [PHP](/sdks/api-clients/apivideo-php-client.md) +- [Go](/sdks/api-clients/apivideo-go-client.md) +- [C#](/sdks/api-clients/apivideo-csharp-client.md) +- [Java](/sdks/api-clients/apivideo-java-client.md) +- [iOS](/sdks/api-clients/ios-api-client.md) +- [Android](/sdks/api-clients/android-api-client.md) -## Installation +## Install To install your selected client, do the following: @@ -78,507 +85,328 @@ Install-Package ApiVideo {% include "_partials/code-tabs.html" content: samples %} -## Create a video container and upload a video +## Upload a video file -When you want to upload a video using the regular way, your video must be under 200 MB. It's a two-step process. First, you create a video container with all your video details and metadata. Then, you retrieve the container's video ID and upload your video into the container using the ID. +![](/_assets/upload-a-file.png) -{% capture samples %} +### Create the video object +The first step to uploading a video is to create a video object. Once you create the object, you can use it to upload a video. Here is the basic minimal code to create the object: + +{% capture samples %} ```curl -curl --request POST \ - --url https://ws.api.video/videos \ - --header 'Accept: application/json' \ - --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI1NDk1NjAuMDE5ODA0LCJuYmYiOjE2NDI1NDk1NjAuMDE5ODA0LCJleHAiOjE2NDI1NTMxNjAuMDE5ODA0LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.jjr4YADGbe62RmBBxJXLy1D61Mtfry_dq9nbriBXgkPrdlBJ8ZRP50CyW3AsGD7wSuKp2mXxEYSzj64zelT1IGOwg6KG4Gz9BZ9YWs0GAHKUIdgqn1gzITX5aQljIXx1fquXbawd-axBTi4icmaUjgXjfnyIcWOgHd2D8A3kpKiqiMmluh58JdnwPnH0OyVk0Rk824P0PI6SxfiTHfkCglPL6ixf9OgokMLPoVrsxH5C0xt3Z7lf5TJ0F78-JY-yTKvyaTTIfI6CFOMNaZUlMtgQwq8X93_2FA65Ntw3hdDML8gFKkLUxnBAtZMo9WAjUd30G4OcYasmlkc4Q_JSNw' \ - --header 'Content-Type: application/json' \ - --data ' +curl --user *your_api_key*: \ +--request POST \ +--url https://ws.api.video/videos \ +--header 'Content-Type: application/json' \ +--data ' { - "public": true, - "panoramic": false, - "mp4Support": true, - "title": "HelloWorld" + "title": "My First Video" } ' - -------Retrieve the access_token from the response, then include in your next request----- - -curl https://ws.api.video/videos/{video ID here}/source \ - -H 'Authorization: Bearer -access token here-' \ - -F file=@yourvideotitle.mp4 ``` -```go -package main - -import ( - "fmt" - "os" - apivideosdk "github.com/apivideo/api.video-go-client" -) - -func main() { - //Connect to production environment - client := apivideosdk.ClientBuilder("YOUR_API_TOKEN").Build() - - // if you rather like to use the sandbox environment: - // client := apivideosdk.SandboxClientBuilder("YOU_SANDBOX_API_TOKEN").Build() - - - //List Videos - //First create the url options for searching - opts := apivideosdk.VideosApiListRequest{}. - CurrentPage(1). - PageSize(25). - SortBy("publishedAt"). - SortOrder("desc") - - //Then call the List endpoint with the options - result, err := client.Videos.List(opts) - - if err != nil { - fmt.Println(err) - } - - for _, video := range result.Data { - fmt.Printf("%s\n", *video.VideoId) - fmt.Printf("%s\n", *video.Title) - } - - - //Upload a video - //First create a container - create, err := client.Videos.Create(apivideosdk.VideoCreationPayload{Title: "My video title"}) - - if err != nil { - fmt.Println(err) - } - - //Then open the video file - videoFile, err := os.Open("path/to/video.mp4") - - if err != nil { - fmt.Println(err) - } - - //Finally upload your video to the container with the videoId - uploadedVideo, err := client.Videos.UploadFile(*create.VideoId, videoFile) - - if err != nil { - fmt.Println(err) - } +```javascript +// First install the "@api.video/nodejs-client" npm package +// Documentation: https://github.com/apivideo/api.video-nodejs-client/blob/main/doc/api/VideosApi.md#create +const client = new ApiVideoClient({ apiKey: "YOUR_API_KEY" }); - //And get the assets - fmt.Printf("%s\n", *uploadedVideo.Assets.Hls) - fmt.Printf("%s\n", *uploadedVideo.Assets.Iframe) -} +const video = await client.videos.create({ title: "My First Video" }); ``` ```php -setTitle('My cool video'); +$video = $client->videos()->create((new \ApiVideo\Client\Model\VideoCreationPayload()) + ->setTitle("My First Video")); +``` +```java +// First add the "video.api:java-api-client" maven dependency to your project +// Documentation: https://github.com/apivideo/api.video-java-client/blob/main/docs/LiveStreamsApi.md#create + +ApiVideoClient client = new ApiVideoClient("YOUR_API_KEY"); -$video = $client->videos()->create($payload); -echo($payload); +VideoCreationPayload videoCreationPayload = new VideoCreationPayload(); +videoCreationPayload.setTitle("My First Video"); -$response = $client->videos()->upload( - $video->getVideoId(), - new SplFileObject(__DIR__.'/VIDEO_TO_UPLOAD.mp4') -); -echo($response); -``` -```javascript -const ApiVideoClient = require('@api.video/nodejs-client'); - -(async () => { - try { - const client = new ApiVideoClient({ apiKey: "YOUR_API_TOKEN" }); - - // create a video - const videoCreationPayload = { - title: "Maths video", // The title of your new video. - description: "A video about string theory.", // A brief description of your video. - }; - const video = await client.videos.create(videoCreationPayload); - - // upload a video file into the video container - await client.videos.upload(video.videoId, "my-video-file.mp4"); - } catch (e) { - console.error(e); - } -})(); +try { + Video video = client.videos().create(videoCreationPayload); +} catch (ApiException e) { + // Manage error here +} ``` -```python Python -import apivideo -from apivideo.apis import VideosApi -from apivideo.exceptions import ApiAuthException +```kotlin +// First add the "video.api:android-api-client" maven dependency to your project +// Documentation: https://github.com/apivideo/api.video-android-client/blob/main/docs/VideosApi.md#create + +val client = ApiVideoClient("YOUR_API_KEY") -api_key = "your api key here" +val videoCreationPayload = VideoCreationPayload() +videoCreationPayload.title = "My First Video" -## Set up the authenticated client -client = apivideo.AuthenticatedApiClient(api_key) +try { + val video = client.videos().create(videoCreationPayload) +} catch (e: ApiException) { + // Manage error here +} +``` +```python +## First install the api client with "pip install api.video" +## Documentation: https://github.com/apivideo/api.video-python-client/blob/main/docs/VideosApi.md#create + +from apivideo.api.videos_api import VideosApi +from apivideo.model.video_creation_payload import VideoCreationPayload +from apivideo import AuthenticatedApiClient, ApiException + +with AuthenticatedApiClient("YOUR_API_KEY") as api_client: + video_creation_payload = VideoCreationPayload( + title="My First Video" + ) + + try: + video = VideosApi(api_client).create(video_creation_payload) + except ApiException as e: + # Manage error here +``` +```go +// First install the go client with go get github.com/apivideo/api.video-go-client +// Documentation: https://github.com/apivideo/api.video-go-client/blob/main/docs/Videos.md#Create + +client := apivideosdk.ClientBuilder("YOUR_API_KEY").Build() -## if you rather like to use the sandbox environment: -## client = apivideo.AuthenticatedApiClient(api_key, production=False) -client.connect() +videoCreationPayload := apivideosdk.VideoCreationPayload{} +videoCreationPayload.SetTitle("My First Video") -videos_api = VideosApi(client) +video, err := client.Videos.Create(videosCreationPayload) -## Create the payload with video details -video_create_payload = { - "title": "Client Video Test", - "description": "Client test", - "public": True, - "tags": ["bunny"] +if video != nil { + // Manage error here } +``` +```swift +// First install the api client: https://github.com/apivideo/api.video-ios-client#getting-started +// Documentation: https://github.com/apivideo/api.video-ios-client/blob/main/docs/VideosAPI.md#create -## Create the container for your video and print the response -response = videos_api.create(video_create_payload) -print("Video Container", response) +ApiVideoClient.apiKey = "YOUR_API_KEY" -## Retrieve the video ID, you can upload once to a video ID -video_id = response["video_id"] +let videoCreationPayload = VideoCreationPayload( + title: "My First Video" +) -## Prepare the file you want to upload. Place the file in the same folder as your code. -file = open("sample-mov-file.mov", "rb") +VideosAPI.create(videoCreationPayload: videoCreationPayload) { video, error in + if let video = video { + // Do something with the video + } + if let error = error { + // Manage error here + } +} +``` +```c# +// First add the "ApiVideo" NuGet package to your project +// Documentation: https://github.com/apivideo/api.video-csharp-client/blob/main/docs/VideosApi.md#create + +var apiVideoClient = new ApiVideoClient("YOUR_API_KEY"); -## Upload your video. This handles videos of any size. The video must be in the same folder as your code. -## If you want to upload from a link online, you need to add the source parameter when you create a new video. -video_response = videos_api.upload(video_id, file) +var videoCreationPayload = new VideoCreationPayload() +{ + title = "My First Video" +}; -print("Uploaded Video", video_response) -``` -```csharp -using System.Collections.Generic; -using System.Diagnostics; -using System; -using System.IO; -using ApiVideo.Api; -using ApiVideo.Client; -using ApiVideo.Model; - -namespace Example +try { - public class Example - { - public static void Main() - { - var apiKey = "YOUR_API_KEY"; - - var apiVideoClient = new ApiVideoClient(apiKey); - // if you rather like to use the sandbox environment: - // var apiVideoClient = new ApiVideoClient(apiKey, ApiVideo.Client.Environment.SANDBOX); - - var videoPayload = new VideoCreationPayload() - { - title = "Example video title", - description = "Example video description", - mp4support = true, - tags = new List() - { - "first","video","test","c#","client" - } - }; - - var myVideoFile = File.OpenRead("my-video.mp4"); - - try { - var newVideo = apiVideoClient.Videos().create(videoPayload); - var video = apiVideoClient.Videos().upload(newVideo.videoid,myVideoFile); - Console.WriteLine(video); - } catch (ApiException e) { - Console.WriteLine(e.ErrorCode); - Console.WriteLine(e.Message); - Console.WriteLine(e.StackTrace); - } - } - } + var video = apiVideoClient.Videos().create(videoCreationPayload); +} +catch (ApiException e) +{ + // Manage error here } ``` - {% endcapture %} -{% include "_partials/code-tabs.html" content: samples %} - +{% include "_partials/code-tabs.md" samples: samples %} -## Create a video container and upload a video over 200 MB with a progressive upload - -When you do a progressive upload for a video, it's because the video is too big to send in one request to api.video. To upload the entire video, it must be broken into chunks, and then each chunk is sent. The smallest chunk size allowed is 5 MiB. When you send using one of the clients, you must indicate when you send the last part. If you implement without a client, then when you send the last part, api.video can tell because your header will say Content-Range: part 3/3 (or whatever number of chunks you sent - 4/4, 8/8, etc.) +{% capture content %} +Replace `your_api_key` by the key you have already copied from dashboard.api.video +{% endcapture %} +{% include "_partials/callout.html" kind: "info", content: content %} -{% capture samples %} +The response to your API request will return the following, along with other params: -```curl -curl --request POST \ - --url https://ws.api.video/videos \ - --header 'Accept: application/json' \ - --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI1NDk1NjAuMDE5ODA0LCJuYmYiOjE2NDI1NDk1NjAuMDE5ODA0LCJleHAiOjE2NDI1NTMxNjAuMDE5ODA0LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.jjr4YADGbe62RmBBxJXLy1D61Mtfry_dq9nbriBXgkPrdlBJ8ZRP50CyW3AsGD7wSuKp2mXxEYSzj64zelT1IGOwg6KG4Gz9BZ9YWs0GAHKUIdgqn1gzITX5aQljIXx1fquXbawd-axBTi4icmaUjgXjfnyIcWOgHd2D8A3kpKiqiMmluh58JdnwPnH0OyVk0Rk824P0PI6SxfiTHfkCglPL6ixf9OgokMLPoVrsxH5C0xt3Z7lf5TJ0F78-JY-yTKvyaTTIfI6CFOMNaZUlMtgQwq8X93_2FA65Ntw3hdDML8gFKkLUxnBAtZMo9WAjUd30G4OcYasmlkc4Q_JSNw' \ - --header 'Content-Type: application/json' \ - --data ' +```json { - "public": true, - "panoramic": false, - "mp4Support": true, - "title": "HelloWorld" + "videoId": "your_video_id_here", + "assets": { + ... + "player": "https://embed.api.video/vod/{videoId}", + ... + } } -' - -# Retrieve the access_token from the response, then include in your next request. - -curl --request POST \ - --url https://ws.api.video/videos//source \ - --header 'Accept: application/json' \ - --header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NDI4MjQzMTkuMDk2NjY1LCJuYmYiOjE2NDI4MjQzMTkuMDk2NjY1LCJleHAiOjE2NDI4Mjc5MTkuMDk2NjY1LCJwcm9qZWN0SWQiOiJwclJ6SUpKQTdCTHNxSGpTNDVLVnBCMSJ9.rfchf3btbMTzSukcwhUS0u4fNY4Q3g1JpoMeIz_Dls1ADmqDdKw7yBOE893C7cagb0lpuvUJvhuhgusLStsJ4nqzTveDeM2oPBQBNJjzwaJZNrImTPD4mif7Tzgxvn1_jQJA5L4gQhjd7frCIJW1yAwywrtiDPbxiWNp8fVl7r_QILjZZfslxy-kblPrHJ20Zix9VURqkGIORY5G_457nHSV9Atks1sUlt49E8b_g3jORja3MnznXBS0-0dksz2K62-QMe1_dk78V9JwbLeydqcr15M1jDLA3H6qFGI7GTsTDdZ5jKLhg5OR6yeSHFysqr3kOteTqAGdp3JuTrpZIA' \ - --header 'Content-Range: part%201%2F3' \ - --header 'Content-Type: multipart/form-data' - -# You would send each part until the last part is sent. In order to do this with a cURL request, you must break your video into chunks ahead of time. ``` -```go -package main -import ( - "context" - "fmt" - "os" - apivideosdk "github.com/apivideo/api.video-go-client" -) +Remember the `videoId`: you will need it to upload your video, in the [next step](#b-upload-the-file-into-the-video-object). +Also, save the value of `assets.player` for [video playback](#watch-your-video). -func main() { - client := apivideosdk.ClientBuilder("YOUR_API_TOKEN").Build() - // if you rather like to use the sandbox environment: - // client := apivideosdk.SandboxClientBuilder("YOU_SANDBOX_API_TOKEN").Build() - - videoId := "vi4k0jvEUuaTdRAEjQ4Jfrgz" // string | Enter the videoId you want to use to upload your video. - - part1, err := os.Open("10m.mp4.part.a") - part2, err := os.Open("10m.mp4.part.b") - part3, err := os.Open("10m.mp4.part.c") - - stream = client.Videos.CreateUploadStream(videoId) - _, err = stream.UploadPartFile(part1) - _, err = stream.UploadPartFile(part2) - res, err := stream.UploadLastPartFile(part3) - - err = part1.Close() - err = part2.Close() - err = part3.Close() -``` -```php -videos()->create((new VideoCreationPayload())->setTitle('Uploaded video')); -$client->videos()->upload($myVideo->getVideoId(), new SplFileObject(__DIR__ . '/../../../tests/resources/558k.mp4')); +const client = new ApiVideoClient({ apiKey: "YOUR_API_KEY" }); -// create a new video & upload a video file using progressive upload (the file is uploaded by parts) -$myVideo2 = $client->videos()->create((new VideoCreationPayload())->setTitle('Uploaded video (progressive upload)')); +// Enter the videoId you want to use to upload your video. +const videoId = 'YOUR_VIDEO_ID'; -$progressiveSession = $client->videos()->createUploadProgressiveSession($myVideo2->getVideoId()); +// The path to the video you would like to upload. The path must be local. +// Instead of a path, you can also use a Readable object, or Buffer. +const file = './my-video.mp4'; + +const video = await client.videos.upload(videoId, file); +``` +```php +// First install the api client: "composer require api-video/php-api-client" +// Documentation: https://github.com/apivideo/api.video-php-client/blob/main/docs/Api/VideosApi.md#upload---upload-a-video -$progressiveSession->uploadPart(new SplFileObject(__DIR__ . '/../../../tests/resources/10m.mp4.part.a')); -$progressiveSession->uploadPart(new SplFileObject(__DIR__ . '/../../../tests/resources/10m.mp4.part.b')); +$client = new \ApiVideo\Client\Client( + 'https://ws.api.video', + 'YOUR_API_KEY', + new \Symfony\Component\HttpClient\Psr18Client() +); -$progressiveSession->uploadLastPart(new SplFileObject(__DIR__ . '/../../../tests/resources/10m.mp4.part.c')); +$client->videos()->upload('YOUR_VIDEO_ID', new SplFileObject(__DIR__ . '/my-video.mp4')); ``` -```javascript -const ApiVideoClient = require('@api.video/nodejs-client'); +```java +// First add the "video.api:java-api-client" maven dependency to your project +// Documentation: https://github.com/apivideo/api.video-java-client/blob/main/docs/VideosApi.md#upload + +ApiVideoClient client = new ApiVideoClient("YOUR_API_KEY"); -(async () => { try { - - const client = new ApiVideoClient({ apiKey: "YOUR_API_TOKEN" }); - - const videoId = 'vi4k0jvEUuaTdRAEjQ4Jfrgz'; // Enter the videoId you want to use to upload your video. - - const uploadSession = client.createUploadProgressiveSession(videoId); - - await uploadSession.uploadPart('test/data/10m.mp4.part.a'); - await uploadSession.uploadPart('test/data/10m.mp4.part.b'); - const res = await uploadSession.uploadLastPart('test/data/10m.mp4.part.c'); // Video - - console.log(result); - } catch (e) { - console.error(e); - } -})(); + Video video = client.videos().upload("YOUR_VIDEO_ID", new File("/path/to/my-video.mp4")); + System.out.println(video); +} catch (ApiException e) { + // Manage error here +} ``` -```python -import os -import apivideo -from apivideo.apis import VideosApi -from apivideo.exceptions import ApiAuthException - -api_key = "your API key here" - -## Set up the authenticated client -client = apivideo.AuthenticatedApiClient(api_key) +```kotlin +// First add the "video.api:android-api-client" maven dependency to your project +// Documentation: https://github.com/apivideo/api.video-android-client/blob/main/docs/VideosApi.md#upload + +val client = ApiVideoClient("YOUR_API_KEY") -## if you rather like to use the sandbox environment: -## client = apivideo.AuthenticatedApiClient(api_key, production=False) -client.connect() - -videos_api = VideosApi(client) - -video_create_payload = { - "title": "Progressive Test", - "description": "test", - "public": False, - "tags": ["nature"] +try { + // Notice: you must not call API from the UI/main thread. Dispatch with Thread, Executors or Kotlin coroutines. + val video = client.videos().upload("YOUR_VIDEO_ID", File("/path/to/my-video.mp4")) +} catch (e: ApiException) { + // Manage error here } -## Create the container for your video and print the response -response = videos_api.create(video_create_payload) -print("Video Container", response) - -## Retrieve the video ID, you can upload once to a video ID -video_id = response["video_id"] - -session = videos_api.create_upload_progressive_session(video_id) - -CHUNK_SIZE = 6000000 - -## This is our chunk reader. This is what gets the next chunk of data ready to send. -def read_in_chunks(file_object, CHUNK_SIZE): - while True: - data = file_object.read(CHUNK_SIZE) - if not data: - break - yield data - -## Upload your file by breaking it into chunks and sending each piece -def upload(file): - content_name = str(file) - content_path = os.path.abspath(file) - - f = open(content_path, "rb") - index = 0 - offset = 0 - part_num = 1 - headers = {} - - for chunk in read_in_chunks(f, CHUNK_SIZE): - offset = index + len(chunk) - index = offset - - with open('chunk.part.' + str(part_num), 'wb') as chunk_file: - chunk_file.write(chunk) - chunk_file.close() - - with open('chunk.part.' + str(part_num), 'rb') as chunk_file: - try: - if len(chunk) == CHUNK_SIZE: - session.uploadPart(chunk_file) - elif len(chunk) < CHUNK_SIZE: - print(session.uploadLastPart(chunk_file)) - chunk_file.close() - except Exception as e: - print(e) - - os.remove('chunk.part.' + str(part_num)) - part_num += 1 - -upload('VIDEO_FILE.mp4') ``` +```python +## First install the api client with "pip install api.video" +## Documentation: https://github.com/apivideo/api.video-python-client/blob/main/docs/VideosApi.md#upload -{% endcapture %} -{% include "_partials/code-tabs.html" content: samples %} - - -## Create a video container and upload a video over 200 MiB with bytes in the content-range header - -A slightly more complicated way to upload a video that's 200 MiB or larger is to use bytes in the content-range header. This method can be complex because if you miscalculate the bytes, it will cause the entire upload to fail. When done correctly, your header will look like this: - -Content-Range: bytes 0-5242879 +import apivideo +from apivideo.api import videos_api +from apivideo.model.video import Video -And then continue from there. By default, the api.video clients handle uploads for you using this method. If you want to try it yourself without the client, the sample will look like this in cURL: +with apivideo.AuthenticatedApiClient("YOUR_API_KEY") as api_client: + video_id = "YOUR_VIDEO_ID" # Enter the videoId you want to use to upload your video. + video_file = open("/path/to/my-video.mp4", "rb") # The path to the video you would like to upload. The path must be local. -{% capture samples %} + try: + video = videos_api.VideosApi(api_client).upload(video_id, video_file) + except ApiException as e: + # Manage error here +``` +```go +// First install the go client with go get github.com/apivideo/api.video-go-client +// Documentation: https://github.com/apivideo/api.video-go-client/blob/main/docs/Videos.md#Upload + +client := apivideosdk.ClientBuilder("YOUR_API_KEY").Build() -```curl -curl -X POST \ - https://sandbox.api.video/auth/api-key \ - -H 'Content-Type: application/json' \ - -d '{"apiKey": "your_api_key"}' - -# Retrieve the access_token from the response, then include in your next request. - -curl -X POST https://sandbox.api.video/videos \ - -H 'Content-Type: application/json' \ - -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFiYjcxNmNiY2ZiNmY4MDc2OWEzZmQ1MjlhMjZiZWRkY2EwMzhlYzA3NDk5M2ZiMTA0YjhiZGMwOTI5MzgxN2M3NmNkNzI4ZDIzOGMzZmNlIn0.eyJhdWQiOiJsaWJjYXN0IiwianRpIjoiYWJiNzE2Y2JjZmI2ZjgwNzY5YTNmZDUyOWEyNmJlZGRjYTAzOGVjMDc0OTkzZmIxMDRiOGJkYzA5MjkzODE3Yzc2Y2Q3MjhkMjM4YzNmY2UiLCJpYXQiOjE1MjY1NDgzMDEsIm5iZiI6MTUyNjU0ODMwMSwiZXhwIjoxNTI2NTUxOTAxLCJzdWIiOiJ1c01vbml0b3IiLCJzY29wZXMiOlsibW9uaXRvci5saWJjYXN0LmNvbSJdLCJjb250ZXh0Ijp7InVzZXIiOiJ1c01vbml0b3IiLCJwcm9qZWN0IjoicHJNb25pdG9yIiwibWVtYmVyIjoibWVNb25pdG9yIn19.jWHC18iEur69FzD5dm78wAwNzh2cPKTRvKuspyQNQKPvhEbYa2v4XhqVNh0TTw8JeNxBtcePBTMHl4S9nWsw7pW4KD8zbqzUjCZNYlaYDpu8vu_tmWVO2JccglJIjuQEaiTbkUsfLdgtsb_9DJ3frk1-WgAKuzu0HewhcGb80xivdJPqNYA6I1Ig8GOief9LTUNNJoqqZn1A1-UiGRTXDag7_yODuxzpMFaAzbaisfK0gYti-PnjyHGWhpGwRplMKPPJk6rSAp1d9TWWXVgg-bNqUzz4_sr33ICJTx7_qZzfamMqk5PDZbHOwpIj8L2DBfo3isvt6QliWmgFEOuvog' \ - -d '{ - "title":"This is a title", - "description":"My video description", - "source":"https://example.com/myVideo.mp4" - }' +videoId := "YOUR_VIDEO_ID" +file, _ := os.Open("./my-video.mp4") -# Split your video into chunks, if you're on a mac you can use this command - -split -b 100m source.mp4.mp4 file_chunk_ - -# Split your video into chunks, if you're using Linux you can use this command - -/path/to/source.mp4` is a 289MB (`281905832 B`) file . - -split --bytes=100M source.mp4 file_chunk_ +video, err := client.Videos.UploadFile(videoId, file) -# You'll need to send a cURL request for each chunk, with the proper Content-Range header +if err != nil { + // Manage error here +} +``` +```swift +// First install the api client: https://github.com/apivideo/api.video-ios-client#getting-started +// Documentation: https://github.com/apivideo/api.video-ios-client/blob/main/docs/VideosAPI.md#upload -curl https://sandbox.api.video/videos/vitq4gOj8GyDT9kyxPQoyNJl/source \ - -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFiYjcxNmNiY2ZiNmY4MDc2OWEzZmQ1MjlhMjZiZWRkY2EwMzhlYzA3NDk5M2ZiMTA0YjhiZGMwOTI5MzgxN2M3NmNkNzI4ZDIzOGMzZmNlIn0.eyJhdWQiOiJsaWJjYXN0IiwianRpIjoiYWJiNzE2Y2JjZmI2ZjgwNzY5YTNmZDUyOWEyNmJlZGRjYTAzOGVjMDc0OTkzZmIxMDRiOGJkYzA5MjkzODE3Yzc2Y2Q3MjhkMjM4YzNmY2UiLCJpYXQiOjE1MjY1NDgzMDEsIm5iZiI6MTUyNjU0ODMwMSwiZXhwIjoxNTI2NTUxOTAxLCJzdWIiOiJ1c01vbml0b3IiLCJzY29wZXMiOlsibW9uaXRvci5saWJjYXN0LmNvbSJdLCJjb250ZXh0Ijp7InVzZXIiOiJ1c01vbml0b3IiLCJwcm9qZWN0IjoicHJNb25pdG9yIiwibWVtYmVyIjoibWVNb25pdG9yIn19.jWHC18iEur69FzD5dm78wAwNzh2cPKTRvKuspyQNQKPvhEbYa2v4XhqVNh0TTw8JeNxBtcePBTMHl4S9nWsw7pW4KD8zbqzUjCZNYlaYDpu8vu_tmWVO2JccglJIjuQEaiTbkUsfLdgtsb_9DJ3frk1-WgAKuzu0HewhcGb80xivdJPqNYA6I1Ig8GOief9LTUNNJoqqZn1A1-UiGRTXDag7_yODuxzpMFaAzbaisfK0gYti-PnjyHGWhpGwRplMKPPJk6rSAp1d9TWWXVgg-bNqUzz4_sr33ICJTx7_qZzfamMqk5PDZbHOwpIj8L2DBfo3isvt6QliWmgFEOuvog' \ - -H 'Content-Range: bytes 0-104857599/281905832' \ - -F file=@/path/to/file_chunk_aa +ApiVideoClient.apiKey = "YOUR_API_KEY" -curl https://sandbox.api.video/videos/vitq4gOj8GyDT9kyxPQoyNJl/source \ - -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFiYjcxNmNiY2ZiNmY4MDc2OWEzZmQ1MjlhMjZiZWRkY2EwMzhlYzA3NDk5M2ZiMTA0YjhiZGMwOTI5MzgxN2M3NmNkNzI4ZDIzOGMzZmNlIn0.eyJhdWQiOiJsaWJjYXN0IiwianRpIjoiYWJiNzE2Y2JjZmI2ZjgwNzY5YTNmZDUyOWEyNmJlZGRjYTAzOGVjMDc0OTkzZmIxMDRiOGJkYzA5MjkzODE3Yzc2Y2Q3MjhkMjM4YzNmY2UiLCJpYXQiOjE1MjY1NDgzMDEsIm5iZiI6MTUyNjU0ODMwMSwiZXhwIjoxNTI2NTUxOTAxLCJzdWIiOiJ1c01vbml0b3IiLCJzY29wZXMiOlsibW9uaXRvci5saWJjYXN0LmNvbSJdLCJjb250ZXh0Ijp7InVzZXIiOiJ1c01vbml0b3IiLCJwcm9qZWN0IjoicHJNb25pdG9yIiwibWVtYmVyIjoibWVNb25pdG9yIn19.jWHC18iEur69FzD5dm78wAwNzh2cPKTRvKuspyQNQKPvhEbYa2v4XhqVNh0TTw8JeNxBtcePBTMHl4S9nWsw7pW4KD8zbqzUjCZNYlaYDpu8vu_tmWVO2JccglJIjuQEaiTbkUsfLdgtsb_9DJ3frk1-WgAKuzu0HewhcGb80xivdJPqNYA6I1Ig8GOief9LTUNNJoqqZn1A1-UiGRTXDag7_yODuxzpMFaAzbaisfK0gYti-PnjyHGWhpGwRplMKPPJk6rSAp1d9TWWXVgg-bNqUzz4_sr33ICJTx7_qZzfamMqk5PDZbHOwpIj8L2DBfo3isvt6QliWmgFEOuvog' \ - -H 'Content-Range: bytes 104857600-209715199/281905832' \ - -F file=@/path/to/file_chunk_ab +VideosAPI.upload(videoId: "YOUR_VIDEO_ID", file: URL(string: "./my-video.mov")) { video, error in + if let video = video { + // Manage upload success here + } + if let error = error { + // Manage upload error here + } + } +``` +```csharp +// First add the "ApiVideo" NuGet package to your project +// Documentation: https://github.com/apivideo/api.video-csharp-client/blob/main/docs/VideosApi.md#Upload + +var apiVideoClient = new ApiVideoClient("YOUR_API_KEY"); -curl https://sandbox.api.video/videos/vitq4gOj8GyDT9kyxPQoyNJl/source \ - -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImFiYjcxNmNiY2ZiNmY4MDc2OWEzZmQ1MjlhMjZiZWRkY2EwMzhlYzA3NDk5M2ZiMTA0YjhiZGMwOTI5MzgxN2M3NmNkNzI4ZDIzOGMzZmNlIn0.eyJhdWQiOiJsaWJjYXN0IiwianRpIjoiYWJiNzE2Y2JjZmI2ZjgwNzY5YTNmZDUyOWEyNmJlZGRjYTAzOGVjMDc0OTkzZmIxMDRiOGJkYzA5MjkzODE3Yzc2Y2Q3MjhkMjM4YzNmY2UiLCJpYXQiOjE1MjY1NDgzMDEsIm5iZiI6MTUyNjU0ODMwMSwiZXhwIjoxNTI2NTUxOTAxLCJzdWIiOiJ1c01vbml0b3IiLCJzY29wZXMiOlsibW9uaXRvci5saWJjYXN0LmNvbSJdLCJjb250ZXh0Ijp7InVzZXIiOiJ1c01vbml0b3IiLCJwcm9qZWN0IjoicHJNb25pdG9yIiwibWVtYmVyIjoibWVNb25pdG9yIn19.jWHC18iEur69FzD5dm78wAwNzh2cPKTRvKuspyQNQKPvhEbYa2v4XhqVNh0TTw8JeNxBtcePBTMHl4S9nWsw7pW4KD8zbqzUjCZNYlaYDpu8vu_tmWVO2JccglJIjuQEaiTbkUsfLdgtsb_9DJ3frk1-WgAKuzu0HewhcGb80xivdJPqNYA6I1Ig8GOief9LTUNNJoqqZn1A1-UiGRTXDag7_yODuxzpMFaAzbaisfK0gYti-PnjyHGWhpGwRplMKPPJk6rSAp1d9TWWXVgg-bNqUzz4_sr33ICJTx7_qZzfamMqk5PDZbHOwpIj8L2DBfo3isvt6QliWmgFEOuvog' \ - -H 'Content-Range: bytes 209715200-281905831/281905832' \ - -F file=@/path/to/file_chunk_ac +var videoFile = File.OpenRead("./my-video.mp4"); +try +{ + var video = apiVideoClient.Videos().upload("YOUR_VIDEO_ID", videoFile) +} +catch (ApiException e) +{ + // Manage error here +} ``` - {% endcapture %} -{% include "_partials/code-tabs.html" content: samples %} +{% include "_partials/code-tabs.md" samples: samples %} +### API response -{% capture content %} -All api.video clients automatically use the `Content-Range: bytes` method to upload big videos for you. You don't have to set it up yourself if you use a client! -{% endcapture %} -{% include "_partials/callout.html" kind: "info", content: content %} +```json +{ + "videoId": "your_video_id", + "assets": { + ... + "player": "https://embed.api.video/vod/{videoId}", + ... + } +} +``` ## Conclusion -If you're just getting started, the two-part upload process is the simplest. If you choose to use one of our clients, handling large files is done for you by the client. If you want to try a progressive upload, these are best when you're working with huge files and you want to send the parts of them concurrently. +If you're just getting started, this two-part upload process is ideal for you. If you choose to use one of our clients, handling large files is done for you by the client. If you want to try a [progressive upload](/vod/progressive-upload.md), these are best when you're working with huge files and you want to send the parts of them concurrently. ## Resources -We offer blog content on this topic: +Check out api.video's blog content on video upload: - [Video upload with cURL](https://api.video/blog/tutorials/video-upload-tutorial) - **cURL** diff --git a/vod/upload-from-source.md b/vod/upload-from-source.md new file mode 100644 index 00000000..3d7ff2ad --- /dev/null +++ b/vod/upload-from-source.md @@ -0,0 +1,354 @@ +--- +title: "Upload video from source" +--- + +## Upload video from source + +api.video enables you to upload a video container file [via a URL](#upload-a-file-from-url), or [clone one of your existing videos](#clone-an-existing-video). + +### Upload a file from a URL + +Uploading a video from a video URL enables you go through the whole video upload process in only 1 step. Paste a URL that points to your video container (for example, the `.mp4` file of your video) into the `source` field in your request: + +{% capture samples %} +```curl +curl --user *your_api_key*: \ +--request POST \ +--url https://ws.api.video/videos \ +--header 'Content-Type: application/json' \ +--data ' +{ + "title": "My First Video", + "source": "https://www.myvideourl.com/video.mp4" +} +' +``` +```javascript +// First install the "@api.video/nodejs-client" npm package +// Documentation: https://github.com/apivideo/api.video-nodejs-client/blob/main/doc/api/VideosApi.md#create + +const client = new ApiVideoClient({ apiKey: "YOUR_API_KEY" }); + +const video = await client.videos.create({ + title: "My First Video", + source: "https://www.myvideourl.com/video.mp4" +}); +``` +```php +// First install the api client: "composer require api-video/php-api-client" +// Documentation: https://github.com/apivideo/api.video-php-client/blob/main/docs/Api/VideosApi.md#create + +$client = new \ApiVideo\Client\Client( + 'https://ws.api.video', + 'YOUR_API_KEY', + new \Symfony\Component\HttpClient\Psr18Client() +); + +$video = $client->videos()->create((new \ApiVideo\Client\Model\VideoCreationPayload()) + ->setTitle("My First Video") + ->setSource("https://www.myvideourl.com/video.mp4")); +``` +```java +// First add the "video.api:java-api-client" maven dependency to your project +// Documentation: https://github.com/apivideo/api.video-java-client/blob/main/docs/LiveStreamsApi.md#create + +ApiVideoClient client = new ApiVideoClient("YOUR_API_KEY"); + +VideoCreationPayload videoCreationPayload = new VideoCreationPayload(); +videoCreationPayload.setTitle("My First Video"); +videoCreationPayload.setSource("https://www.myvideourl.com/video.mp4"); + +try { + Video video = client.videos().create(videoCreationPayload); +} catch (ApiException e) { + // Manage error here +} +``` +```kotlin +// First add the "video.api:android-api-client" maven dependency to your project +// Documentation: https://github.com/apivideo/api.video-android-client/blob/main/docs/VideosApi.md#create + +val client = ApiVideoClient("YOUR_API_KEY") + +val videoCreationPayload = VideoCreationPayload() +videoCreationPayload.title = "My First Video" +videoCreationPayload.source = "https://www.myvideourl.com/video.mp4" + +try { + val video = client.videos().create(videoCreationPayload) +} catch (e: ApiException) { + // Manage error here +} +``` +```python +## First install the api client with "pip install api.video" +## Documentation: https://github.com/apivideo/api.video-python-client/blob/main/docs/VideosApi.md#create + +from apivideo.api.videos_api import VideosApi +from apivideo.model.video_creation_payload import VideoCreationPayload +from apivideo import AuthenticatedApiClient, ApiException + +with AuthenticatedApiClient("YOUR_API_KEY") as api_client: + video_creation_payload = VideoCreationPayload( + title="My First Video", + source="https://www.myvideourl.com/video.mp4" + ) + + try: + video = VideosApi(api_client).create(video_creation_payload) + except ApiException as e: + # Manage error here +``` +```go +// First install the go client with go get github.com/apivideo/api.video-go-client +// Documentation: https://github.com/apivideo/api.video-go-client/blob/main/docs/Videos.md#Create + +client := apivideosdk.ClientBuilder("YOUR_API_KEY").Build() + +videoCreationPayload := apivideosdk.VideoCreationPayload{} +videoCreationPayload.SetTitle("My First Video") +videoCreationPayload.SetSource("https://www.myvideourl.com/video.mp4") + +video, err := client.Videos.Create(videosCreationPayload) + +if video != nil { + // Manage error here +} +``` +```swift +// First install the api client: https://github.com/apivideo/api.video-ios-client#getting-started +// Documentation: https://github.com/apivideo/api.video-ios-client/blob/main/docs/VideosAPI.md#create + +ApiVideoClient.apiKey = "YOUR_API_KEY" + +let videoCreationPayload = VideoCreationPayload( + title: "My First Video", + source: "https://www.myvideourl.com/video.mp4" +) + +VideosAPI.create(videoCreationPayload: videoCreationPayload) { video, error in + if let video = video { + // Do something with the video + } + if let error = error { + // Manage error here + } +} +``` +```csharp +// First add the "ApiVideo" NuGet package to your project +// Documentation: https://github.com/apivideo/api.video-csharp-client/blob/main/docs/VideosApi.md#create + +var apiVideoClient = new ApiVideoClient("YOUR_API_KEY"); + +var videoCreationPayload = new VideoCreationPayload() +{ + title = "My First Video", + source = "https://www.myvideourl.com/video.mp4" +}; + +try +{ + var video = apiVideoClient.Videos().create(videoCreationPayload); +} +catch (ApiException e) +{ + // Manage error here +} +``` +{% endcapture %} +{% include "_partials/code-tabs.md" samples: samples %} + +{% capture content %} +Replace the link in the example above with your video container (for example, the `.mp4` file of your video). If you don’t have a video URL to test this, you can use [this one](http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4) for example. +{% endcapture %} +{% include "_partials/callout.html" kind: "info", content: content %} + +### Clone an existing video + +You can clone a video that already exists in your api.video project. Just paste your video's `videoId` into the `source` field in your request: + +{% capture samples %} +```curl +curl --user *your_api_key*: \ +--request POST \ +--url https://ws.api.video/videos \ +--header 'Content-Type: application/json' \ +--data ' +{ + "title": "My Cloned Video", + "source": "your_video_id_here" +} +' +``` +```javascript +// First install the "@api.video/nodejs-client" npm package +// Documentation: https://github.com/apivideo/api.video-nodejs-client/blob/main/doc/api/VideosApi.md#create + +const client = new ApiVideoClient({ apiKey: "YOUR_API_KEY" }); + +const video = await client.videos.create({ + title: "My Cloned Video", + source: "your_video_id_here" +}); +``` +```php +// First install the api client: "composer require api-video/php-api-client" +// Documentation: https://github.com/apivideo/api.video-php-client/blob/main/docs/Api/VideosApi.md#create + +$client = new \ApiVideo\Client\Client( + 'https://ws.api.video', + 'YOUR_API_KEY', + new \Symfony\Component\HttpClient\Psr18Client() +); + +$video = $client->videos()->create((new \ApiVideo\Client\Model\VideoCreationPayload()) + ->setTitle("My Cloned Video") + ->setSource("your_video_id_here")); +``` +```java +// First add the "video.api:java-api-client" maven dependency to your project +// Documentation: https://github.com/apivideo/api.video-java-client/blob/main/docs/LiveStreamsApi.md#create + +ApiVideoClient client = new ApiVideoClient("YOUR_API_KEY"); + +VideoCreationPayload videoCreationPayload = new VideoCreationPayload(); +videoCreationPayload.setTitle("My Cloned Video"); +videoCreationPayload.setSource("your_video_id_here"); + +try { + Video video = client.videos().create(videoCreationPayload); +} catch (ApiException e) { + // Manage error here +} +``` +```kotlin +// First add the "video.api:android-api-client" maven dependency to your project +// Documentation: https://github.com/apivideo/api.video-android-client/blob/main/docs/VideosApi.md#create + +val client = ApiVideoClient("YOUR_API_KEY") + +val videoCreationPayload = VideoCreationPayload() +videoCreationPayload.title = "My Cloned Video" +videoCreationPayload.source = "your_video_id_here" + +try { + val video = client.videos().create(videoCreationPayload) +} catch (e: ApiException) { + // Manage error here +} +``` +```python +## First install the api client with "pip install api.video" +## Documentation: https://github.com/apivideo/api.video-python-client/blob/main/docs/VideosApi.md#create + +from apivideo.api.videos_api import VideosApi +from apivideo.model.video_creation_payload import VideoCreationPayload +from apivideo import AuthenticatedApiClient, ApiException + +with AuthenticatedApiClient("YOUR_API_KEY") as api_client: + video_creation_payload = VideoCreationPayload( + title="My Cloned Video", + source="your_video_id_here" + ) + + try: + video = VideosApi(api_client).create(video_creation_payload) + except ApiException as e: + # Manage error here +``` +```go +// First install the go client with go get github.com/apivideo/api.video-go-client +// Documentation: https://github.com/apivideo/api.video-go-client/blob/main/docs/Videos.md#Create + +client := apivideosdk.ClientBuilder("YOUR_API_KEY").Build() + +videoCreationPayload := apivideosdk.VideoCreationPayload{} +videoCreationPayload.SetTitle("My Cloned Video") +videoCreationPayload.SetSource("your_video_id_here") + +video, err := client.Videos.Create(videosCreationPayload) + +if video != nil { + // Manage error here +} +``` +```swift +// First install the api client: https://github.com/apivideo/api.video-ios-client#getting-started +// Documentation: https://github.com/apivideo/api.video-ios-client/blob/main/docs/VideosAPI.md#create + +ApiVideoClient.apiKey = "YOUR_API_KEY" + +let videoCreationPayload = VideoCreationPayload( + title: "My Cloned Video", + source: "your_video_id_here4" +) + +VideosAPI.create(videoCreationPayload: videoCreationPayload) { video, error in + if let video = video { + // Do something with the video + } + if let error = error { + // Manage error here + } +} +``` +```csharp +// First add the "ApiVideo" NuGet package to your project +// Documentation: https://github.com/apivideo/api.video-csharp-client/blob/main/docs/VideosApi.md#create + +var apiVideoClient = new ApiVideoClient("YOUR_API_KEY"); + +var videoCreationPayload = new VideoCreationPayload() +{ + title = "My Cloned Video", + source = "your_video_id_here" +}; + +try +{ + var video = apiVideoClient.Videos().create(videoCreationPayload); +} +catch (ApiException e) +{ + // Manage error here +} +``` +{% endcapture %} +{% include "_partials/code-tabs.md" samples: samples %} + +### API response + +```json +202 - Accepted video object creation from source URL or source Video ID (for cloning) + +{ + "videoId": "your_video_id_here", + "assets": { + ... + "player": "https://embed.api.video/vod/{videoId}", + ... + } +} +``` + +## Watch your video + +The easiest way to play your video is to use the [api.video](http://api.video) player URL that you received in the [ API response](#api-response): + +`"player": "https://embed.api.video/vod/{videoId}"` + +To watch your video, just paste the link into your favorite browser. + +## Manage your video + +You can do many things to manage existing videos in your [api.video](http://api.video) environment: + +- [Update a video](/reference/api/Videos#update-a-video-object) (API) +- [List all videos](/reference/api/Videos#list-all-video-objects) (API) +- [Delete a video](/reference/api/Videos#delete-a-video-object) (API) +- [Upload a thumbnail to a video](/reference/api/Videos#upload-a-thumbnail) (API) +- [Pick a thumbnail for a video](/reference/api/Videos#set-a-thumbnail) (API) +- [Retrieve a video](/reference/api/Videos#retrieve-a-video-object) (API) +- [Retrieve a video status](/reference/api/Videos#retrieve-video-status-and-details) (API) +- [Retrieve raw statistics about your video](/reference/api/Raw-statistics#list-video-player-sessions) (API) diff --git a/vod/upload-your-first-video.md b/vod/upload-your-first-video.md index aff941d1..c5d9c848 100644 --- a/vod/upload-your-first-video.md +++ b/vod/upload-your-first-video.md @@ -16,7 +16,7 @@ Upload Your First Video Before you can start uploading your first video, you need to [create an account](https://dashboard.api.video/register). -Once you are logged in to dashboard.api.video, select the environment of your choice (sandbox or production), and copy your API key: +Once you are logged in to dashboard.api.video, select the environment of your choice (sandbox or production), and copy your API key. ## 2. Upload a video diff --git a/vod/using-tokens.md b/vod/using-tokens.md index 19562975..7849e4bd 100644 --- a/vod/using-tokens.md +++ b/vod/using-tokens.md @@ -1,7 +1,15 @@ -api.video provides you with various options of authentication which allows you to leverage the API on a different level of your application, whether it's on the front end or backend. Moreover, you can provide better security for your backend and videos. +--- +title: "Using upload tokens" +slug: "using-tokens" +metadata: + title: "Using upload tokens" + description: "This guide explains the various options of API authentication for uploading videos." +--- # Upload & API Access Tokens +api.video provides you with various options of authentication which allows you to leverage the API on a different level of your application, whether it's on the front end or backend. Moreover, you can provide better security for your backend and videos. + ## Access Token This token is created to enhance the backend security and create a short-lived bearer token that will replace your API key for any API request. The Access Token is a disposable bearer token that is being generated from the [/auth/api-key](https://docs.api.video/reference/post_auth-api-key) endpoint, by passing the workspace API key. The endpoint will respond with a short-lived bearer token (3600 seconds) that can be refreshed by making a request to the [/auth/refresh](https://docs.api.video/reference/post_auth-refresh) endpoint. diff --git a/vod/using-video-metadata.md b/vod/using-video-metadata.md deleted file mode 100644 index 8edf65a2..00000000 --- a/vod/using-video-metadata.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: "Using video metadata for analytic" -slug: "using-video-metadata" -metadata: - title: "Using video metadata for analytic • api.video Documentation" - description: "TBA" ---- - -Using video metadata for analytic -========== - -TBA \ No newline at end of file diff --git a/vod/video-upload.md b/vod/video-upload.md deleted file mode 100644 index ad3499c7..00000000 --- a/vod/video-upload.md +++ /dev/null @@ -1 +0,0 @@ -what-is-api-video.md \ No newline at end of file