Skip to content

chunkifydev/chunkify-go

Repository files navigation

chunkify-black

The next generation Cloud transcoding service.

Latest Release Build status

Chunkify Go

The official Go library for the Chunkify API.

Requirements

  • Go 1.22 or higher

Installation

You can install the Chunkify Go library using go get:

go get github.com/chunkifydev/chunkify-go

Usage

Creating a Client

First, you'll need to create a client instance to interact with the API. You can create one with default settings or with custom configuration:

import "github.com/chunkifydev/chunkify-go"

// Create a new client instance with default settings
client := chunkify.NewClient(chunkify.AccessTokens{
    TeamToken: "sk_team_token",
	ProjectToken: "sk_project_token",
})

You can initialize the client with custom configuration:

config := chunkify.Config{
    AccessTokens: chunkify.AccessTokens{
        TeamToken:    "sk_team_token",
        ProjectToken: "sk_project_token",
    },
    Timeout: 60 * time.Second,
}
client = chunkify.NewClientWithConfig(config)

Creating a Source from a Local File

You will need to upload your file, to do so you first need to create an upload entry. This will enable the creation of a source from it upon upload completion:

// First create an upload entry
uploadResponse, err := client.UploadCreate(chunkify.UploadCreateParams{
    Metadata: chunkify.UploadCreateParamsMetadata{
        "key": "value",
    },
})
if err != nil {
	t.Fatalf("Error creating upload: %v", err)
}
// Open a file to upload
file, err := os.Open("path/to/your/file.mp4")
if err != nil {
    log.Fatal(err)
}
defer file.Close()

// Upload the file using the obtained upload response
err = client.UploadBlob(context.TODO(), file, uploadResponse)
if err != nil {
    log.Fatal(err)
}

// Upon successful upload a new source will be created.

Creating a Source from an Hosted File

If your file is already hosted online, you can create a source directly from its URL:

// Create a new source
source, err := client.SourceCreate(chunkify.SourceCreateParams{
    Url: "http://somevideos.com/your_source.mp4",
    Metadata: chunkify.SourceCreateParamsMetadata{
        "key": "value",
    },
})

if err != nil {
	t.Fatalf("Error creating source: %v", err)
}

fmt.Printf("New source: %s (%dx%d) with codec %s\n", source.Id, source.Width, source.Height, source.VideoCodec)

Creating Jobs

Here is an example of job creation:

// Create a new job with a custom template
config := &chunkify.H264{
    Video: &chunkify.Video{
        Height:       chunkify.Int64(1080),
        Framerate:    chunkify.Int64(30),
        VideoBitrate: chunkify.Int64(5000000), // 5 Mbps
        AudioBitrate: chunkify.Int64(128000),  // 128 Kbps
    },
}

// JobCreateFormatParams has a field for each supported format
// You must use the appropriate field for the format you want to use
job, err := client.JobCreate(chunkify.JobCreateParams{
    SourceId: source.Id,
    Format: chunkify.JobCreateFormatParams{
        Mp4H264: config,
    },
})

// If you want to use an encoding format but with no specific parameters, you must provide an empty struct
job, err := client.JobCreate(chunkify.JobCreateParams{
    SourceId: source.Id,
    Format: chunkify.JobCreateFormatParams{
        WebmVp9: &chunkify.Vp9{},
    },
})

Listing Jobs

The library provides paginated access to your jobs. Here's how to list jobs with filtering and pagination:

// Configure pagination and filtering parameters
params := chunkify.JobListParams{
    Limit:  chunkify.Int64(10),
    Offset: chunkify.Int64(0),
    Status: chunkify.String(chunkify.JobStatusCompleted),
}

// Get the first page of results
result, err := client.JobList(params)
if err != nil {
    log.Fatal(err)
}

// Access the current page of jobs
for _, job := range result.Items {
    fmt.Printf("Job ID: %s, Status: %s\n", job.Id, job.Status)
}

// Get the next page
nextPage, err := result.Next()
if err != nil {
    // An error is returned if there is no next page available.
    log.Fatal(err)
}
// Process next page...

Customizing the number of transcoders and CPU

By default, we choose automatically the right number of transcoder with the right CPU. If you want to customize this behavior, you can pass the options like this:

job, err := client.JobCreate(chunkify.JobCreateParams{
    SourceId: source.Id,
    Format: chunkify.JobCreateFormatParams{
        Mp4H264: config,
    },
    Transcoder: &chunkify.JobCreateTranscoderParams{
        Quantity: 10,
        Type: chunkify.TranscoderType8vCPU,
    },
})

Available CPU Resources

The library client automatically tracks the available CPU resources from the API responses. You can access this information through the LastAvailableCpuCount field:

// LastAvailableCpuCount will be -1 (CpuCountUnknown) until the first API response
if client.LastAvailableCpuCount == chunkify.CpuCountUnknown {
    fmt.Println("CPU count not yet available")
} else {
    fmt.Printf("Available CPUs: %d\n", client.LastAvailableCpuCount)
}

Handling Webhooks

To ensure that webhook notifications are coming from Chunkify, you should verify the signature of each request. Here's an example showing how to do it:

// In your webhook handler
func handleWebhook(w http.ResponseWriter, r *http.Request) {
    // Get the signature from the X-Chunkify-Signature header
    signature := r.Header.Get("X-Chunkify-Signature")

    // Read the request body
    body, err := io.ReadAll(r.Body)
    if err != nil {
        http.Error(w, "Error reading request body", http.StatusBadRequest)
        return
    }

    // Verify the signature using your signature key
    if !chunkify.VerifyNotificationSignature(body, signature, "your_signature_key") {
        http.Error(w, "Invalid signature", http.StatusUnauthorized)
        return
    }

    // Parse the webhook payload
    var payload chunkify.NotificationPayload
    if err := json.Unmarshal(body, &payload); err != nil {
        http.Error(w, "Error parsing webhook", http.StatusBadRequest)
        return
    }

    fmt.Println("Received notification", payload.Id, payload.Event)

    switch data := payload.Data.(type) {
	case *chunkify.NotificationPayloadJobCompletedData:
		fmt.Printf("Job %s completed with %d files\n", data.Job.Id, len(data.Files))
	default:
		fmt.Printf("unexpected payload data type: %T\n", data)
	}
}

Handling Errors

The library provides structured error handling with semantic error types and detailed API error information. You can handle errors gracefully:

client := chunkify.NewClient(chunkify.AccessTokens{
    TeamToken: "sk_team_token",
	ProjectToken: "sk_project_token",
})

source, err := client.SourceCreate(chunkify.SourceCreateParams{
        Url: "http://somevideos.com/your_source.mp4",
})
if err != nil {
    // Check if it's an API error and get detailed information
    var apiError chunkify.ApiError
    if errors.As(err, &apiError) {
        fmt.Printf("API Error Type: %s\n", apiError.Type)
        fmt.Printf("HTTP Status Code: %d\n", apiError.Code)
        fmt.Printf("Error Message: %s\n", apiError.Message)
    } else {
        // Handle other types of errors (network, parsing, etc.)
        fmt.Printf("Error: %v\n", err)
    }
    return
}
 

The library provides predefined error variables for semantic error checking:

  • ErrAuthentication - Invalid API key
  • ErrValidation - Invalid input parameters
  • ErrNotFound - Resource not found
  • ErrTooManyRequests - Rate limit exceeded
  • ErrForbidden - Permission denied
  • ErrUnexpected - Server errors
client := chunkify.NewClient(chunkify.AccessTokens{
    TeamToken: "sk_team_token",
    ProjectToken: "sk_project_token",
})

source, err := client.SourceCreate(chunkify.SourceCreateParams{
    Url: "http://somevideos.com/your_source.mp4",
})
if err != nil {
    if errors.Is(err, chunkify.ErrAuthentication) {
        // Handle auth issues
        fmt.Println("Authentication failed - check your API keys")
    } else if errors.Is(err, chunkify.ErrValidation) {
        // Handle validation issues
        fmt.Println("Invalid parameters provided")
    } else if errors.Is(err, chunkify.ErrTooManyRequests) {
        // Implement retry logic
        fmt.Println("Rate limited - please retry later")
    } else {
        // Handle other errors
        fmt.Printf("Unexpected error: %v\n", err)
    }
    return
}

About

Chunkify Go Library

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages