# API # API Documentation ## Contents [Parameters](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/api-documentation#bkmrk-parameters) [Cloud Credentials](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/api-documentation#bkmrk-cloud-credentials) [Cloud Credentials Input/Output](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/api-documentation#bkmrk-cloud-credentials-in) [Audio Profiles](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/api-documentation#bkmrk-audio-profiles) [Video Profiles](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/api-documentation#bkmrk-video-profiles) [Supported Containers and Codecs](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/api-documentation#bkmrk-supported-containers) [Creating Jobs](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/creating-curl-jobs) [ Using the API from within Python](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/code) [Retrieving a Sent Job](http://docs.streamengine.igolgi.com/books/igolgi-stream-engine/page/creating-curl-jobs#bkmrk-retrieving-a-sent-jo) ### Parameters #### input or not to use this input. This will be an object key if using a cloud provider, or a regular URL otherwise.
TypeRequiredDefault
stringYes
#### videoProfiles An array containing at least one video profile.
TypeRequiredDefault
arrayYes
#### audioProfiles An array containing zero or more audio profiles.
TypeRequiredDefault
arrayYes
#### output\_container Output container to be used. Supported values are ts, mp4, hls, and silverlight .
TypeRequiredDefault
stringNomp4
#### ts\_mode\_input\_audio\_source\_stream\_count Audio stream count (in TS mode only).
TypeRequiredDefault
numberNo
#### audio\_output\_path The cloud location where audio should be stored.
TypeRequiredDefault
stringNo
#### bucket\_output\_path The location, within a cloud bucket, where the output should be stored in segmented mode.
TypeRequiredDefault
stringNo
#### master\_variant\_mode Whether or not to use separate audio.
TypeRequiredDefault
booleanNofalse
#### segmented\_output\_hls Whether to use HLS in segmented output.
TypeRequiredDefault
booleanNofalse
#### segmented\_output\_dash Whether to use DASH in segmented output.
TypeRequiredDefault
booleanNofalse
#### segment\_length The segment length in segmented output.
TypeRequiredDefault
numberNo
#### video\_codec Output video encoder. Supported values are h.264, mpeg2, and hevc.
TypeRequiredDefault
stringNoh.264
#### ip\_distance Target I/P frame distance.
TypeRequiredDefault
numberNo
#### gop\_length Target GOP length in seconds.
TypeRequiredDefault
numberNo1
#### scte35\_passthough Use SCTE35 passthrough?
TypeRequiredDefault
booleanNofalse
#### scte35\_pid\_remap PID Remap.
TypeRequiredDefault
numberNo
#### create\_tar\_file In segmented output, whether to tar the resulting directory and store it in the same bucket specified by the bucket\_output\_path parameter. Note that this will take up more space in your bucket.
TypeRequiredDefault
booleanNo
#### audio\_volume Target audio volume (0-200).
TypeRequiredDefault
numberNo100
#### h264\_quality Output quality. Accepted values are 'good', 'better', and 'best'. Supported values are good, better , and best.
TypeRequiredDefault
stringNogood
#### video\_aspect\_ratio Output video aspect ratio. Supported values are passthrough, force\_4:3, force\_16:9, invert\_aspect\_ratio, rotate\_counterclockwise , rotate\_clockwise, and rotate\_counterclockwise + invert\_aspect\_ratio.
TypeRequiredDefault
stringNopassthrough
#### rotation\_blackness ... .
TypeRequiredDefault
numberNo
#### closed\_captions Write CC to output?
TypeRequiredDefault
booleanNo
#### force\_progressive Force progressive?
TypeRequiredDefault
booleanNofalse
#### keep\_fps Preserve the framerate?
TypeRequiredDefault
booleanNotrue
#### logo\_url URL to an image file to use as a watermark.
TypeRequiredDefault
stringNo
#### cloud\_credentials See Below
TypeRequiredDefault
objectYes
### Cloud Credentials #### input
TypeRequiredDefault
object Yes
#### output
TypeRequiredDefault
object Yes
### Cloud Credentials Input/Output #### cloud\_provider The cloud provider to use
Supported values are aws, oracle, gcloud, http, file-upload, igolgi-store .
TypeRequiredDefault
stringYesoracle
#### access\_key Account access key.
TypeRequiredDefault
stringNo
#### secret\_key Account secret key.
TypeRequiredDefault
stringNo
#### region The region within which your target bucket is located.
TypeRequiredDefault
stringNo
\------ #### tenancy\_ocid Tenancy OCID (for oracle only)
TypeRequiredDefault
stringNo
#### user\_ocid User OCID (for oracle only)
TypeRequiredDefault
stringNo
#### oci\_fingerprint User Fingerprint (for oracle only)
TypeRequiredDefault
stringNo
#### project\_id Project ID (for google only)
TypeRequiredDefault
stringNo
#### client\_email Client email (for google only)
TypeRequiredDefault
stringNo
#### client\_id Client ID (for google only)
TypeRequiredDefault
stringNo
#### private\_key\_id Private Key ID (for google only)
TypeRequiredDefault
stringNo
### Audio Profiles #### audio\_codec Audio codec to be used during transcode. Supported values are aac, ac3 or mp2.
TypeRequiredDefault
stringNoaac
#### audio\_channels Number of audio channels on the output. Use 2 for stereo and 6 for 5.1. Supported values are 2 or 6.
TypeRequiredDefault
stringNo2
#### audio\_bitrate Output audio bitrate. Supported values are 32, 40, 64, 96, 128, 192, 256, 384, 448 or 768.
TypeRequiredDefault
stringNo256
#### primary\_audio\_downmix\_to\_stereo Downmix primary audio from 5.1 to stereo.
TypeRequiredDefault
booleanNo
#### source\_stream The index of the source stream. Supported values are 1 , 2 , 3 , 4 , 5 , 6 , 7 or 8.
TypeRequiredDefault
stringNo
#### dolby\_digital\_dialnorm The dialnorm. Values range from 0 to 31 inclusive. Use 0 for passthrough.
TypeRequiredDefault
numberNo
### Video Profiles #### output The location, including the file name, where the output is to be sent.
TypeRequiredDefault
stringNo
#### width The output width in pixels.
TypeRequiredDefault
numberYes
#### height The output height in pixels
TypeRequiredDefault
numberYes
#### video\_bitrate\_mode Output video bitrate mode. Supported values are cbr or vbr.
TypeRequiredDefault
stringNo
#### video\_bitrate The video bitrate in kbps.
TypeRequiredDefault
numberYes
#### video\_framerate The video framerate. Supported values are 1x, 1/2x or 2x.
TypeRequiredDefault
stringNo1x
#### audio\_profiles
TypeRequiredDefault
stringNo
### Supported Containers and Codecs - Input Containers: MXF, MPEG2-TS and MP4 - Output Containers: MPEG2-TS, MP4 - Input Codecs: MPEG2, ProRes, XDCAM, H.264, HEVC for video; AC3, MPEG2, AAC for audio - Output Codecs: MPEG2, H.264 and HEVC for video; Passthrough, AAC-LC and AAC 5.1 for audio, AC3 stereo and 5.1 for audio ### Creating Jobs ### Using the API from within Python ### Retrieving a Sent Job Job Status: {'job\_id': '4765', 'tcode\_progress': '100', 'state': 'ready', 'tcode\_time': '57.89', 'tcode\_speed': '0.0', 'job\_completed': True, 'xfer\_speed': '337.88', 'xfer\_time': '0.67', 'xfer\_progress': '100'} Job Config: {'input': 'https://streamengine.igolgi.com/uploads/659d9ac25dc7bf7b1a7c487a971a98e8', 'videoProfiles': \[{'output': 'oci://yzwhip2gci7s/igolgi-public/80d8cc2a\_bdab\_442b\_bc19\_21fe00267a34.mp4', 'width': 0, 'height': 0, 'video\_bitrate': 6000, 'video\_framerate': '1x'}\], 'audioProfiles': \[{'audio\_codec': 'aac', 'audio\_channels': 2, 'audio\_bitrate': 128, 'primary\_audio\_downmix\_to\_stereo': False, 'source\_stream': 1}\], 'output\_container': 'mp4', 'audio\_output\_path': 'oci://yzwhip2gci7s/igolgi-public/96dbafd7\_bf4f\_45a8\_bd06\_627a4684e45b.mp4', 'separate\_audio': True, 'segmented\_output\_hls': False, 'segmented\_output\_dash': False, 'video\_codec': 'hevc', 'ip\_distance': 3, 'gop\_length': 2, 'scte35\_passthough': False, 'scte35\_pid\_remap': -1, 'create\_tar\_file': False, 'audio\_volume': 100, 'h264\_quality': 'good', 'video\_aspect\_ratio': 'rotate\_counterclockwise + invert\_aspect\_ratio', 'rotation\_blackness': 0, 'closed\_captions': False, 'picture\_transform': 'none', 'logo\_url': None} # Getting Started with curl & API - Hidden This section is targeted to new users with minimal programming experience to get the most out of the power of StreamEngine. If you are an advanced user you may want to skip over this section and go to the next section. CURL is a Command URL which allows you to pass commands through a url. In StreamEngine you can pass special variables to help re-encode your videos. If you have a lot of videos you can automate processes to process your videos using curl or the API. API is the application program interface which is usually used to talk from one application to another. If you have an application you can use our API to automate video conversion. # cURL 101 - hidden
curl https://streamengine.igolgi.com/api/v0/job \\ --request POST \\ -u 0123456789abcdefghijklmnop:a \\ --header 'Content-Type: application/json' \\ -d '{ "videoProfiles": \[ { "width": 960, "height": 544, "video\_bitrate": 750, "video\_framerate": "1x", "audio\_profiles": "0" } \], "master\_variant\_mode": false, "segmented\_output\_dash": false, "output\_container": "mp4", "picture\_transform": "none", "logo\_url": null, "audio\_volume": 100, "closed\_captions": false, "create\_tar\_file": false, "gop\_length": 2, "h264\_quality": "better", "scte35\_pid\_remap": -1, "video\_aspect\_ratio": "passthrough", "rotation\_blackness": 0, "scte35\_passthough": false, "segmented\_output\_hls": false, "ip\_distance": 2, "audioProfiles": \[ { "audio\_codec": "aac", "audio\_channels": 2, "audio\_bitrate": 256, "primary\_audio\_downmix\_to\_stereo": false, "source\_stream": 1 } \], "input": "s3://igolgi-se-in/GOPR8286-720-120fps.MP4", "cloud\_credentials": { "input": { "cloud\_provider": "aws", "access\_key": "ABCDEFGHIJKLMNOPQRST", "secret\_key": "AaBbCcDdEeFfGgHhIiJjKkLlMm+/NnOoPpQqRrSsTtUuVvWwXxYyZz", "region": "us-east-2", "tenancy\_ocid": null, "user\_ocid": null, "oci\_fingerprint": null }, "output": { "cloud\_provider": "igolgi-store", "access\_key": null, "secret\_key": null, "region": "ca-toronto-1", "tenancy\_ocid": null, "user\_ocid": null, "oci\_fingerprint": null } }, "force\_progressive": true, "keep\_fps": true, "video\_codec": "h.264" }'application server url link **POST** - sends the following data to the server link above **-u** (user account, get api key) **:a** is for auto login, otherwise it will prompt for a password. This tells what format the code is in "json" format -d run all code between '{ ... }'
# Creating cURL Jobs ### Creating Jobs To create a job, use your API key along with a JSON payload matching the schema described in the tables above, and make an HTTP GET request like the following: ``` curl https://streamengine.igolgi.com/api/v0/job \ -k \ --request POST \ -u 8e6f7a5bf90821a175338ce08be4b7ca:a \ --header 'Content-Type: application/json' \ -d '{ "videoProfiles": [ { "output": "", "width": 1024, "height": 768, "video_bitrate": 3500, "video_bitrate_mode": "cbr", "video_framerate": "1x" } ], "audioProfiles": [ { "audio_bitrate": 256, "audio_channels": 2, "audio_codec": "aac" } ], "output_container": "mp4", "video_codec": "h.264", "input": "oci://yzwhip2gci7s/jey_test_bucket2/test_dir/moana_30_seconds.ts", "cloud_credentials": { "input": { "cloud_provider": "oracle", "access_key": "...", "secret_key": "...", "region": "ca-toronto-1" } } }' ``` ### Retrieving a Sent Job To retrieve a job, use your API key to make a GET request to the /api/v0/job/id endpoint, replacing id with the id of the job you wish to retrieve: ``` curl https://streamengine.igolgi.com/api/v0/job/1 \ -u 8e6f7a5bf90821a175338ce08be4b7ca: ``` The response will look something like this: ``` { "status": { "tcode_progress": "0", "state": "ready", ... # additional fields }, "config": { ... # your job configuration }, } ``` This allows you to retrieve the original configuration for your job, as well as check on its progress using the tcode\_progress field. # API task - Relationship tables - hidden Depending on what options you choose, different options can be required. In the basic form not much is required # Variables - hidden close Variables change based on what options are selected. Blue is default setting, although defaults may change depending on options selected. I.E. if you select h.264 encoding you will see h264\_quality: good, better, best' but if its not selected you will not see the option. When cloud storage options are on you will see other options that relate to the specific cloud service. curl https://streamengine.igolgi.com/api/v0/job -k \\ \--request POST \\ -u 1a944b985b09c14b5001ba5cc1a1f585:a \\ --header 'Content-Type: application/json' \\ -d '{ "videoProfiles": \[ { "width": 1280, "height": 720, "video\_bitrate": 2200, "video\_framerate": "1x", "audio\_profiles": "0" } \], "separate\_audio": true/false, "segmented\_output\_dash": false, "output\_container": "mp4", mp4 or ts "picture\_transform": "none", "logo\_url": null, "audio\_volume": 100, 0-200, "closed\_captions": true/false "create\_tar\_file": true/false "gop\_length": 2 (seconds) "h264\_quality": "good, better, best", (only displayed when video\_codec = h264) "scte35\_pid\_remap": -1, "video\_aspect\_ratio": "passthrough", 'force\_4:3', 'force\_16:9', 'invert\_aspect\_ratio', 'rotate\_counterclockwise', 'rotate\_clockwise', 'rotate\_counterclockwise + invert\_aspect\_ratio', 'rotate\_clockwise + invert\_aspect\_ratio, "rotation\_blackness": 0, "video\_codec": "h.264", "scte35\_passthough": false, "segmented\_output\_hls": false, "ip\_distance": 2, (i-frame or key frame distance in frames) "audioProfiles": \[ { "audio\_codec": "aac", "audio\_channels": 2, "audio\_bitrate": 256, "primary\_audio\_downmix\_to\_stereo": false, "source\_stream": 1 } \], "input": "https://streamengine.igolgi.com/uploads/b7b6127de1344d2ae1f221cd5797bb66", "cloud\_credentials": { "input": { "cloud\_provider": "file-upload", "access\_key": null, "secret\_key": null, "region": "ca-toronto-1", "tenancy\_ocid": null, (needed to access oci api and support) "user\_ocid": null, "oci\_fingerprint": null }, "output": { "cloud\_provider": "igolgi-store", "access\_key": null, "secret\_key": null, "region": "ca-toronto-1", "tenancy\_ocid": null, "user\_ocid": null, "oci\_fingerprint": null } } }' $ python3 se-aws-status.py 13302 (front end job\_id) Job Status: { 'job\_id': '4767', job\_id on backend server, not the same as frontend job\_id 'tcode\_progress': '100', transcode progress 0-100 where 100 is finished 'state': 'ready', 'tcode\_time': '18.06', transcode time 'tcode\_speed': '0.0', transcode speed, displays when running the job 'job\_completed': True, or False shows when the job as been completed 'xfer\_speed': '169.1', transfer speed 'xfer\_time': '0.25', time to transfer 'xfer\_progress': '100' transfer progress in percent 0-100 } GOP is Group of Pictures - **the distance between two keyframes, measured in the number of frames, or the amount of time between keyframes**. For example, if a keyframe is inserted every 1 second into a video at 30 frames per second, the GOP length is 30 frames, or 1 second. A key frame is a whole frame full image, like a photo. An I-frame is only the part of the image that's changing. By only showing what is changing videos can be smaller in size. gop length seconds (some documentation shows this in frames, jeff says seconds) ip distance is frames Selecting Tar as an options Save as tar, tar is a compressed file similar to zip but for Linux, macOS and Windows 11 update 23H2 or higher. You can open a tar file in windows 10 using command line or you can use a third party app like free opensource 7-zip found at [https://www.7-zip.com](https://www.7-zip.com) . On windows 10 search for "cmd" and select "Run as Administrator" [![image.png](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/scaled-1680-/THEimage.png)](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/THEimage.png) You may get a popup windows asking "Do you want to allow this app to make changes to your device?", if so click Yes. A command window will popup, navigate to the directory where the tar file is. [![image.png](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/scaled-1680-/tZCimage.png)](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/tZCimage.png) Then run **tar -xf tarfilename.tar** and it will extract the file into the current directory. In the example in the image above we ran **tar -xf test.tar** and it extracted 3 files from the tar file and put them in the current directory. ... do we want to explain how to install and run 7-zip [![image.png](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/scaled-1680-/Ad3image.png)](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/Ad3image.png) # Go Examples This is an example in Go, please modify it to fit your environment, be sure to change the video input and output paths as well as the API\_KEY and AWS\_ACCESS and AWS\_SECRET keys. ```go package main import ( "bytes" "encoding/json" "fmt" "io/ioutil" "net/http" ) func main() { url := "https://streamengine.igolgi.com/api/v0/job" // Authentication credentials username := "INSERT_YOUR_API_KEY" password := "a" // Data to be sent in the POST request data := map[string]interface{}{ "videoProfiles": []map[string]interface{}{ { "output": "s3://igolgi-se-out/go-testcwaudio3f.mp4", "width": 1920, "height": 1080, "video_bitrate_mode": "cbr", "video_bitrate": 2301, "video_format": "progressive", "video_framerate": "1x", "audio_profiles": "1", }, }, "audioProfiles": []map[string]interface{}{ { "audio_bitrate": 256, "audio_channels": 2, "audio_codec": "aac", "source_stream": 1, }, }, "master_variant_mode": false, "output_container": "mp4", "video_codec": "h.264", "input": "s3://igolgi-se-in/GOPR8297-2.7K-30-fps.MP4", "auto_detelecine_flag": false, "cloud_credentials": map[string]interface{}{ "input": map[string]string{ "cloud_provider": "aws", "access_key": "INSERT_YOUR_AWS_ACCESS_KEY", "secret_key": "INSERT_YOUR_AWS_SECRET_KEY", "region": "us-east-2", }, "output": map[string]string{ "cloud_provider": "aws", "access_key": "INSERT_YOUR_AWS_ACCESS_KEY", "secret_key": "INSERT_YOUR_AWS_SECRET_KEY", "region": "us-east-2", }, }, } jsonData, err := json.Marshal(data) if err != nil { fmt.Println("Error marshalling JSON:", err) return } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { fmt.Println("Error creating request:", err) return } req.Header.Set("Content-Type", "application/json") req.SetBasicAuth(username, password) client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response:", err) return } fmt.Println("Response:", string(body)) } ``` save the script above as se\_api\_aws.go or similar run go run se\_api\_aws.go it will give print something like: Response: {"\_auto\_generated\_id\_":**13455**,"cloud":"aws" .... Remember your job number above and use it with the following script to check the status. ```go package main import ( "encoding/base64" "encoding/json" "fmt" "io/ioutil" "net/http" "os" ) func main() { if len(os.Args) < 2 { fmt.Println("Please provide a job ID as an argument.") os.Exit(1) } jobID := os.Args[1] url := fmt.Sprintf("https://streamengine.igolgi.com/api/v0/job/%s", jobID) apiKey := "INSERT_YOUR_API_KEY" // Replace with your actual API key req, err := http.NewRequest("GET", url, nil) if err != nil { fmt.Println("Error creating request:", err) return } // Set Authorization header authHeader := base64.StdEncoding.EncodeToString([]byte(apiKey + ":")) req.Header.Set("Authorization", "Basic "+authHeader) client := &http.Client{} resp, err := client.Do(req) if err != nil { fmt.Println("Error sending request:", err) return } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response:", err) return } if resp.StatusCode == 200 { var data map[string]interface{} err = json.Unmarshal(body, &data) if err != nil { fmt.Println("Error parsing JSON:", err) return } fmt.Println("Job Status:") fmt.Println("------------------------") status := data["status"].(map[string]interface{}) fmt.Printf("Job ID: %s\n", status["job_id"]) fmt.Printf("State: %s\n", status["state"]) fmt.Println("Progress:") fmt.Printf(" Transcode: %v%%\n", status["tcode_progress"]) fmt.Printf(" Transfer: %v%%\n", status["xfer_progress"]) fmt.Println("Time:") fmt.Printf(" Transcode: %v seconds\n", status["tcode_time"]) fmt.Printf(" Transfer: %v seconds\n", status["xfer_time"]) fmt.Println("Speed:") fmt.Printf(" Transcode: %v x\n", status["tcode_speed"]) fmt.Printf(" Transfer: %v MB/s\n", status["xfer_speed"]) fmt.Printf("Job Completed: %v\n", status["job_completed"]) fmt.Println("\nJob Config:") fmt.Println("------------------------") config, err := json.MarshalIndent(data["config"], "", " ") if err != nil { fmt.Println("Error formatting config:", err) } else { fmt.Println(string(config)) } } else { fmt.Printf("Failed to retrieve job. Status code: %d\n", resp.StatusCode) fmt.Printf("Response: %s\n", string(body)) } } ``` Save the script above as se-api-status.go or similar. Run go run se-api-status.go **13455** You'll see a result similar to the one below. The job ID of status will be different than the submit job id. You can rerun the status until you see Job Completed: true. ``` Job Status: ------------------------ Job ID: 4920 State: ready Progress: Transcode: 0% Transfer: 0% Time: Transcode: seconds Transfer: 78460.45 seconds Speed: Transcode: -1 x Transfer: -1.0 MB/s Job Completed: false Job Config: ------------------------ { "audioProfiles": [ { "audio_bitrate": 256, "audio_channels": 2, "audio_codec": "aac", "source_stream": 1 } ], "audio_volume": 100, "gop_length": 1, "h264_quality": "good", "input": "s3://igolgi-se-in/GOPR8297-2.7K-30-fps.MP4", "output_container": "mp4", "picture_transform": "none", "scte35_passthough": false, "segmented_output_dash": false, "segmented_output_hls": false, "separate_audio": false, "videoProfiles": [ { "audio_profiles": "1", "height": 1080, "output": "s3://igolgi-se-out/go-testcwaudio3f.mp4", "video_bitrate": 2301, "video_bitrate_mode": "cbr", "video_framerate": "1x", "width": 1920 } ], "video_aspect_ratio": "passthrough", "video_codec": "h.264" } ``` On linux/Ubuntu if you have never used go. You can run: $ sudo apt update $ sudo apt install golang-go # Javascript Examples The following code sample was written in java using the fetch method. It requires an API\_KEY and FILE\_NUMBER\_OF\_UPLOADED\_VIDEO Depending on your operating system you will need node.js loaded [https://nodejs.org/en ](https://nodejs.org/en) and this code can be run: node se-localfile.mjs node --experimental-modules se-localfile.mjs se-localfile.mjs ```javascript import fetch from 'node-fetch'; const url = 'https://streamengine.igolgi.com/api/v0/job'; const username = 'API_KEY'; const password = 'a'; const headers = { 'Authorization': 'Basic ' + Buffer.from(username + ":" + password).toString('base64'), 'Content-Type': 'application/json' }; const data = { videoProfiles: [ { width: 960, height: 544, video_bitrate: 2500, video_framerate: "1x", audio_profiles: "0" } ], separate_audio: false, segmented_output_dash: false, output_container: "mp4", picture_transform: "none", logo_url: null, audio_volume: 100, closed_captions: false, create_tar_file: false, gop_length: 2, h264_quality: "good", scte35_pid_remap: -1, video_aspect_ratio: "rotate_counterclockwise + invert_aspect_ratio", rotation_blackness: 0, scte35_passthough: false, segmented_output_hls: false, ip_distance: 2, audioProfiles: [ { audio_codec: "aac", audio_channels: 2, audio_bitrate: 256, primary_audio_downmix_to_stereo: false, source_stream: 1 } ], input: "https://streamengine.igolgi.com/uploads/FILE_NUMBER_OF_UPLOADED_VIDEO", cloud_credentials: { input: { cloud_provider: "file-upload", access_key: null, secret_key: null, region: "ca-toronto-1", tenancy_ocid: null, user_ocid: null, oci_fingerprint: null }, output: { cloud_provider: "igolgi-store", access_key: null, secret_key: null, region: "ca-toronto-1", tenancy_ocid: null, user_ocid: null, oci_fingerprint: null } }, master_variant_mode: false, video_codec: "h.264" }; fetch(url, { method: 'POST', headers: headers, body: JSON.stringify(data) }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ``` --- se-job-status.mjs `$node se-job-status.mjs  job-id` This sample script will run every 10 seconds to see if a job is still running, when its finished it will display finished, feel free to modify this. ```javascript import fetch from 'node-fetch'; const checkJobStatus = async (jobId) => { const url = `https://streamengine.igolgi.com/api/v0/job/${jobId}`; // Adjust this URL as needed const username = 'API_KEY'; const password = 'a'; const headers = { 'Authorization': 'Basic ' + Buffer.from(username + ":" + password).toString('base64'), 'Content-Type': 'application/json' }; try { const response = await fetch(url, { method: 'GET', headers: headers }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); console.log('Job status:', data); return data; } catch (error) { console.error('Error checking job status:', error); } }; const checkUntilComplete = async (jobId) => { let status; do { const result = await checkJobStatus(jobId); status = result.status; // Adjust this based on the actual API response structure if (status !== 'completed') { console.log('Job still in progress. Waiting 10 seconds before checking again...'); await new Promise(resolve => setTimeout(resolve, 10000)); // Wait for 10 seconds } } while (status !== 'completed'); console.log('Job completed!'); }; // Get job ID from command line argument const jobId = process.argv[2]; if (!jobId) { console.error('Please provide a job ID as a command-line argument.'); console.error('Usage: node se-job-status.mjs '); process.exit(1); } console.log(`Checking status for job ID: ${jobId}`); checkUntilComplete(jobId); ``` # Ruby Examples Feel free to modify the following script for your environment. To process the video, this script below assumes your job is on aws in an S3 bucket for input and output. ```ruby require 'net/http' require 'uri' require 'json' url = URI.parse("https://streamengine.igolgi.com/api/v0/job") headers = { 'Content-Type' => 'application/json' } # Authentication credentials (username and password) auth = ['INSERT_YOUR_API_KEY', 'a'] # Data to be sent in the POST request data = { videoProfiles: [ { output: 's3://igolgi-se-out/rb-testcwaudio3e.mp4', width: 1920, height: 1080, video_bitrate_mode: 'cbr', video_bitrate: 2400, video_format: 'progressive', video_framerate: '1x', audio_profiles: '1' } ], audioProfiles: [ { audio_bitrate: 256, audio_channels: 2, audio_codec: 'aac', source_stream: 1 } ], master_variant_mode: false, output_container: "mp4", video_codec: "h.264", input: "s3://igolgi-se-in/GOPR8297-2.7K-30-fps.MP4", auto_detelecine_flag: false, cloud_credentials: { input: { cloud_provider: "aws", access_key: "INSERT_YOUR_AWS_ACCESS_KEY", secret_key: "INSERT_YOUR_AWS_SECRET_KEY", region: "us-east-2" }, output: { cloud_provider: "aws", access_key: "INSERT_YOUR_AWS_ACCESS_KEY", secret_key: "INSERT_YOUR_AWS_SECRET_KEY", region: "us-east-2" } } } http = Net::HTTP.new(url.host, url.port) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE # Not recommended for production request = Net::HTTP::Post.new(url.path, headers) request.basic_auth(auth[0], auth[1]) request.body = data.to_json response = http.request(request) # Print the response content puts response.body ``` Save the file as **se-api-aws.rb** or similar. Run: ruby se-api-aws.rb You may notice an error like this: ...error ... message: "The video bitrate for this profile and codec should set at a minimum of 2300."... The error above means the video\_bitrate variable in the code should be higher than 2300, it was already changed in the code above, but used as an example of the messages you might see. When it runs correctly you might see something similar to this: `{"_auto_generated_id_":13453,..."updated_at":"2024-07-16T18:49:57.000Z"}` The Id number can also be found on the Job History page. [![image.png](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/scaled-1680-/0NRimage.png)](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/0NRimage.png) If you want to see the status of the job from ruby you can use this code: ``` require 'net/http' require 'uri' require 'json' # Check if an argument was provided if ARGV.length > 0 external_var = ARGV[0] else puts "Please provide a job ID as an argument." exit end # Define the URL and API key url = URI.parse("https://streamengine.igolgi.com/api/v0/job/#{external_var}") api_key = "1a944b985b09c14b5001ba5cc1a1f585" # Set up the HTTP request http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url.request_uri) request.basic_auth(api_key, '') # Make the GET request response = http.request(request) # Check for a successful response if response.code == '200' puts "Job Status:" puts "------------------------" puts "Job ID: #{data['status']['job_id']}" puts "State: #{data['status']['state']}" puts "Progress:" puts " Transcode: #{data['status']['tcode_progress']}%" puts " Transfer: #{data['status']['xfer_progress']}%" puts "Time:" puts " Transcode: #{data['status']['tcode_time']} seconds" puts " Transfer: #{data['status']['xfer_time']} seconds" puts "Speed:" puts " Transcode: #{data['status']['tcode_speed']} x" puts " Transfer: #{data['status']['xfer_speed']} MB/s" puts "Job Completed: #{data['status']['job_completed']}" puts "\nJob Config:" puts "------------------------" puts JSON.pretty_generate(data['config']) else puts "Failed to retrieve job. Status code: #{response.code}" puts "Response: #{response.body}" end ``` Save the file above as **se\_api\_status.rb** or similar Run **ruby se\_api\_status.rb 13453** where 13453 is the job number ``` Job Status: ------------------------ Job ID: 4918 State: ready Progress: Transcode: 100% Transfer: 0% Time: Transcode: 19.06 seconds Transfer: 28.29 seconds Speed: Transcode: 0.0 x Transfer: 0.0 MB/s Job Completed: true Job Config: ------------------------ { "input": "s3://igolgi-se-in/GOPR8297-2.7K-30-fps.MP4", "videoProfiles": [ { "output": "s3://igolgi-se-out/py2-testcwaudio3e.mp4", "width": 1920, "height": 1080, "video_bitrate_mode": "cbr", "video_bitrate": 2400, "video_framerate": "1x", "audio_profiles": "1" } ], "audioProfiles": [ { "audio_codec": "aac", "audio_channels": 2, "audio_bitrate": 256, "source_stream": 1 } ], "output_container": "mp4", "separate_audio": false, "segmented_output_hls": false, "segmented_output_dash": false, "video_codec": "h.264", "gop_length": 1, "scte35_passthough": false, "audio_volume": 100, "h264_quality": "good", "video_aspect_ratio": "passthrough", "picture_transform": "none" } ``` # Python Examples The following example uses video files on AWS in an S3 bucket and writes files out to a different AWS S3 Bucket. ```python import requests url = "https://streamengine.igolgi.com/api/v0/job" headers = { 'Content-Type': 'application/json', } # Authentication credentials (username and password) auth = ('INSERT_YOUR_API_KEY', 'a') # Data to be sent in the POST request data = { 'videoProfiles': [ { 'output': 's3://igolgi-se-out/py2-testcwaudio3d.mp4', 'width': 1920, 'height': 1080, 'video_bitrate_mode': 'cbr', 'video_bitrate': 2250, # there are minimum bitrates see tables 'video_format': 'progressive', 'video_framerate': '1x', 'audio_profiles': '1' # required if you want audio 0 - 7 }], 'audioProfiles': [ { 'audio_bitrate': 256, 'audio_channels': 2, 'audio_codec': 'aac', 'source_stream': 1 # required if you want audio 1 - 8 }], "master_variant_mode": False, "output_container": "mp4", "video_codec": "h.264", "input": "s3://igolgi-se-in/GOPR8297-2.7K-30-fps.MP4", "auto_detelecine_flag": False, "cloud_credentials": { "input": { "cloud_provider": "aws", "access_key": "INSERT_YOUR_AWS_ACCESS_KEY", "secret_key": "INSERT_YOUR_AWS_SECRET_KEY", "region": "us-east-2" }, "output": { "cloud_provider": "aws", "access_key": "INSERT_YOUR_AWS_ACCESS_KEY", "secret_key": "INSERT_YOUR_AWS_SECRET_KEY", "region": "us-east-2" } } } # Disable SSL verification (not recommended for production) response = requests.post(url, json=data, headers=headers, auth=auth) # Print the response content print(response.content.decode('utf-8')) ``` ```python import requests import sys import json from requests.auth import HTTPBasicAuth if len(sys.argv) > 1: external_var = sys.argv[1] else: print("Please provide a job ID as an argument.") sys.exit(1) # Define the URL and API key url = f"https://streamengine.igolgi.com/api/v0/job/{external_var}" api_key = "INSERT_YOUR_API_KEY" # Make the GET request response = requests.get(url, auth=HTTPBasicAuth(api_key, '')) # Check for a successful response if response.status_code == 200: data = response.json() status = data.get("status", {}) config = data.get("config", {}) print("Job Status:") print("------------------------") print(f"Job ID: {status.get('job_id')}") print(f"State: {status.get('state')}") print("Progress:") print(f" Transcode: {status.get('tcode_progress')}%") print(f" Transfer: {status.get('xfer_progress')}%") print("Time:") print(f" Transcode: {status.get('tcode_time')} seconds") print(f" Transfer: {status.get('xfer_time')} seconds") print("Speed:") print(f" Transcode: {status.get('tcode_speed')} x") print(f" Transfer: {status.get('xfer_speed')} MB/s") print(f"Job Completed: {status.get('job_completed')}") print("\nJob Config:") print("------------------------") print(json.dumps(config, indent=2)) else: print(f"Failed to retrieve job. Status code: {response.status_code}") print("Response:", response.text) ``` ``` Job Status: ------------------------ Job ID: 4920 State: ready Progress: Transcode: 100% Transfer: 0% Time: Transcode: 19.94 seconds Transfer: 27.87 seconds Speed: Transcode: 0.0 x Transfer: 0.0 MB/s Job Completed: True Job Config: ------------------------ { "input": "s3://igolgi-se-in/GOPR8297-2.7K-30-fps.MP4", "videoProfiles": [ { "output": "s3://igolgi-se-out/go-testcwaudio3f.mp4", "width": 1920, "height": 1080, "video_bitrate_mode": "cbr", "video_bitrate": 2301, "video_framerate": "1x", "audio_profiles": "1" } ], "audioProfiles": [ { "audio_codec": "aac", "audio_channels": 2, "audio_bitrate": 256, "source_stream": 1 } ], "output_container": "mp4", "separate_audio": false, "segmented_output_hls": false, "segmented_output_dash": false, "video_codec": "h.264", "gop_length": 1, "scte35_passthough": false, "audio_volume": 100, "h264_quality": "good", "video_aspect_ratio": "passthrough", "picture_transform": "none" } ``` # Stream videos with HTML-DASH and HLS Why would I want to use hls or dash? Dash and Hls are great for streaming large files and give the user the ability to jump around in the video, fast forward, rewind or jump to an index. In the past you needed expensive streaming servers and serve videos using rtsp: or mms: In StreamEngine convert a file you want to stream from a website to mp4-hls, mp4-dash or mp4-hls+dash. This will create a tar or tar.gz file DASH - Dynamic Adaptive Streaming over HTTP then copy the file to your webserver and name it playlist.m3u8 or modify the <source src = "playlist.m3u8" ... line below. ```html HLS-DASH Player ``` This HTML file does the following: 1. It includes the video.js CSS and JavaScript files from a CDN. 2. It creates a video player using the `video-js` tag. 3. It sets the source of the video to your `playlist.m3u8` file. 4. It initializes the video.js player and attempts to start playback. To use this: 1. Save this HTML code to a file (e.g., `player.html`) on your web server. 2. Make sure your `playlist.m3u8` file is in the same directory as the HTML file, or update the `src` attribute with the correct path to your playlist file. 3. Access the HTML file through your web server (e.g., `https://yourserver.com/player.html`). Note: - Ensure that your web server is correctly configured to serve the `.m3u8` file with the correct MIME type (`application/x-mpegURL`). - The player's size is set to 640x360 pixels. You can adjust these values as needed. - This example uses video.js version 7.20.3. You may want to check for the latest version and update the URLs accordingly. # Curl - Check Job Status When you submit a curl job you should get a response back from the StreamEngine server with the job id on it. #### Curl - Linux and Windows curl -u API\_KEY:a -H "Content-Type: application/json" https://streamengine.igolgi.com/api/v0/job/<JOB\_ID> replace API\_KEY with your StreamEngine API Key replace <JOB\_ID> If you only want to see job status and have jq installed on linux you can run curl -u API\_KEY:a -H "Content-Type: application/json" https://streamengine.igolgi.com/api/v0/job/<JOB\_ID> | jq ".status" ```shell $ curl -u API_KEY:a -H "Content-Type: application/json" https://streamengine.igolgi.com/api/v0/job/ | jq ".status" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1079 100 1079 0 0 9989 0 --:--:-- --:--:-- --:--:-- 10084 { "job_id": "5087", "tcode_progress": "100", "state": "ready", "tcode_time": "36.84", "tcode_speed": "0.0", "job_completed": true, "xfer_speed": "0.0", "xfer_time": "86398.93", "xfer_progress": "100" } ``` Note the job\_id above (backend) will be different than is the <JOB\_ID> submitted which is the id of the frontend, or ```shell $ curl -u API_KEY:a -H "Content-Type: application/json" https://streamengine.igolgi.com/api/v0/job/ | jq ".status.job_completed" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1079 100 1079 0 0 9099 0 --:--:-- --:--:-- --:--:-- 9144 true ``` [jq is available for Windows](https://jqlang.github.io/jq/download/), use at your own risk, it's a separate install, AMD64 executable should work with intel. Windows cmd, note API\_KEY blurred out. [![curl - powershell-check-jobstatus.png](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/scaled-1680-/curl-powershell-check-jobstatus.png)](http://docs.streamengine.igolgi.com/uploads/images/gallery/2024-07/curl-powershell-check-jobstatus.png) On Windows with PowerShell. PowerShell is a little different curl works but -u option does not so we will need to write a program. ```powershell param( [Parameter(Mandatory=$true)] [string]$JobId ) $url = "https://streamengine.igolgi.com/api/v0/job/$JobId" $username = "API_KEY" $password = "a" $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password))) $headers = @{ Authorization = "Basic $base64AuthInfo" "Content-Type" = "application/json" } try { $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get Write-Host "Status for Job ID: $JobId" Write-Host "Full status:" $response.status | ConvertTo-Json Write-Host "`nKey status fields:" Write-Host "State: $($response.status.state)" Write-Host "Job Completed: $($response.status.job_completed)" Write-Host "Tcode Progress: $($response.status.tcode_progress)%" Write-Host "Xfer Progress: $($response.status.xfer_progress)%" } catch { Write-Host "Error checking job status: $_" } ``` save it to a file for example CheckJobStatus.ps1 Then you can run the script above. .\\CheckJobStatus.ps1 -JobID <JOB\_ID> Linux shell script if you want to store your API key an reuse it with a script. ```bash #!/bin/bash JOB_ID=$1 if [ -z "$JOB_ID" ]; then     echo "Please provide a job ID as an argument."     echo "Usage: ./check_job_status.sh "     exit 1 fi echo "Checking status for job ID: $JOB_ID" while true; do     response=$(curl -s -u API_KEY:a -H "Content-Type: application/json" https://streamengine.igolgi.com/api/v0/job/$JOB_ID)     status=$(echo $response | jq -r '.status')          echo "Job status: $status"          if [ "$status" = "completed" ]; then         echo "Job completed!"         break     else         echo "Job still in progress. Waiting 10 seconds before checking again..."         sleep 10     fi done ``` Curl - Windows PowerShell Here is another example on Windows in PowerShell .\\CheckJobStatus.ps1 -JobId <Your-Job-ID> ```powershell param(     [Parameter(Mandatory=$true)]     [string]$JobId ) $url = "https://streamengine.igolgi.com/api/v0/job/$JobId" $username = "API_KEY" $password = "a" $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $username,$password))) $headers = @{     Authorization = "Basic $base64AuthInfo"     "Content-Type" = "application/json" } function Check-JobStatus {     try {         $response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get         return $response     }     catch {         Write-Host "Error checking job status: $_"         return $null     } } Write-Host "Checking status for job ID: $JobId" do {     $result = Check-JobStatus     if ($result -ne $null) {         $status = $result.status  # Adjust this if the API response structure is different         Write-Host "Job status: $status"                  if ($status -ne "completed") {             Write-Host "Job still in progress. Waiting 10 seconds before checking again..."             Start-Sleep -Seconds 10         }     }     else {         Write-Host "Failed to get job status. Retrying in 10 seconds..."         Start-Sleep -Seconds 10     } } while ($status -ne "completed") Write-Host "Job completed!" ```