Skip to content

Commit 7d9e16f

Browse files
authored
Java: Code example for Generating video with Nova Reel / Bedrock (#7360)
* Add nova reel video generation app example --------- Co-authored-by: Brian Murray <40031786+brmur@users.noreply.github.com> (added metadata)
1 parent d67e2ff commit 7d9e16f

File tree

9 files changed

+362
-0
lines changed

9 files changed

+362
-0
lines changed

.doc_gen/metadata/bedrock-runtime_metadata.yaml

+17
Original file line numberDiff line numberDiff line change
@@ -1648,3 +1648,20 @@ bedrock-runtime_Scenario_InvokeModels:
16481648
- php.example_code.bedrock-runtime.basics.scenario
16491649
services:
16501650
bedrock-runtime: {InvokeModel, InvokeModelWithResponseStream}
1651+
1652+
bedrock-runtime_Scenario_GenerateVideos_NovaReel:
1653+
title: Generate videos from text prompts using &BR; and Nova-Reel
1654+
title_abbrev: "Generate videos from text prompts using &BR;"
1655+
synopsis: a Spring Boot app that generates videos from text prompts using &BR; and the Nova-Reel model.
1656+
category: Scenarios
1657+
languages:
1658+
Java:
1659+
versions:
1660+
- sdk_version: 2
1661+
github: javav2/example_code/bedrock-runtime
1662+
excerpts:
1663+
- description: Generate videos from text prompts using &BR; and Nova-Reel.
1664+
snippet_tags:
1665+
- bedrock-runtime.java2.NovaReel.VideoGeneration
1666+
services:
1667+
bedrock-runtime: {StartAsyncInvoke, GetAsyncInvoke}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# NovaReel Video Generation Service
2+
3+
This is a Spring Boot application that provides a REST API to generate videos from text prompts using Amazon Bedrock and the Nova-Reel model.
4+
5+
## Overview
6+
7+
The application enables asynchronous video generation using AWS Bedrock's `amazon.nova-reel-v1:0` model and stores the generated videos in an S3 bucket.
8+
9+
It consists of:
10+
- A REST controller for handling API requests
11+
- A service class to interact with Amazon Bedrock
12+
- A response model for encapsulating result data
13+
14+
## Project Structure
15+
![](images/structure.png)
16+
- **NovaReelDemo.java** Main class to bootstrap the Spring Boot app
17+
- **GenerateVideoResponse.java** Response DTO with fields: executionArn, s3Bucket, status
18+
- **VideoGenerationService.java** Service for interacting with Amazon Bedrock
19+
- **VideoGeneratorController.java** REST controller exposing /video endpoints
20+
21+
## Functionality
22+
23+
### 1. Generate Video
24+
**Endpoint:** POST /video/generate
25+
**Query Param:** prompt (string)
26+
**Description:**
27+
- Takes a text prompt
28+
- Sends an async request to `amazon.nova-reel-v1:0` using Bedrock
29+
- The generated video will be stored in the specified S3 bucket in 3-5 mins
30+
- Returns the executionArn
31+
32+
### 2. Check Status
33+
**Endpoint:** POST /video/check
34+
**Query Param:** invocationArn (string)
35+
**Description:**
36+
- Checks the generation status of a video using invocationArn
37+
- Returns the current status
38+
39+
## Configuration
40+
41+
### Prerequisites
42+
43+
- AWS account with access to Amazon Bedrock
44+
- AWS credentials configured via named profile (e.g. `~/.aws/credentials`)
45+
- A valid S3 bucket for output (currently hardcoded)
46+
47+
### Modify S3 Bucket
48+
49+
In `VideoGenerationService.java`, update the following line:
50+
`String s3Bucket = "s3://add_your_bucket_here";`
51+
Replace with your own S3 bucket URI where videos should be saved.
52+
53+
### AWS Credentials
54+
55+
By default, credentials are loaded from a named profile using:
56+
`ProfileCredentialsProvider.create()`
57+
Make sure you have the profile set in your `~/.aws/config` or override it as needed.
58+
59+
### IAM Permissions
60+
Because Amazon Bedrock writes a file to an Amazon S3 bucket on your behalf, the AWS role that you use needs permissions configured to allow the appropriate Amazon Bedrock and Amazon S3 actions
61+
The minimum action permissions required to execute this application are:
62+
63+
```
64+
bedrock:InvokeModel
65+
s3:PutObject
66+
bedrock:GetAsyncInvoke
67+
bedrock:ListAsyncInvokes
68+
```
69+
70+
71+
## How to Run
72+
73+
1. Clone the repo
74+
2. Update the S3 bucket in `VideoGenerationService.java`
75+
3. Set up AWS credentials
76+
4. Build and run the Spring Boot application:
77+
`./mvnw spring-boot:run`
78+
5. Use an API client (e.g. Postman or curl) to interact with the endpoints
79+
80+
## Example Requests
81+
82+
### Generate Video
83+
```
84+
curl -X POST "http://localhost:8080/video/generate?prompt=A cat surfing on a pizza in space"
85+
```
86+
87+
### Check Status
88+
```
89+
curl -X POST "http://localhost:8080/video/check?invocationArn=<your-arn-here>"
90+
```
91+
when status is Completed - video generated and stored in S3 bucket
92+
93+
## Dependencies
94+
95+
- Spring Boot Web
96+
- AWS SDK v2 (Bedrock Runtime)
97+
- Jackson / JSON
98+
- Maven or Gradle for build
99+
100+
101+
## Future Improvements
102+
103+
- Make S3 bucket configurable via `application.yml`
104+
- Add status polling endpoint that waits until generation is complete
105+
- Integrate with frontend or S3 browser to retrieve the generated video
106+
107+
## Additional Materials
108+
109+
- [Amazon Bedrock Overview](https://aws.amazon.com/bedrock/)
110+
- [Amazon Nova Reel - AWS AI Service Cards](https://docs.aws.amazon.com/ai/responsible-ai/nova-reel/overview.html)
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.springframework.boot</groupId>
9+
<artifactId>spring-boot-starter-parent</artifactId>
10+
<version>3.4.1</version>
11+
<relativePath/> <!-- lookup parent from repository -->
12+
</parent>
13+
14+
<groupId>com.example</groupId>
15+
<artifactId>nova-reel-test</artifactId>
16+
<version>1.0-SNAPSHOT</version>
17+
18+
<properties>
19+
<maven.compiler.source>17</maven.compiler.source>
20+
<maven.compiler.target>17</maven.compiler.target>
21+
</properties>
22+
23+
<dependencies>
24+
25+
<dependency>
26+
<groupId>org.springframework.boot</groupId>
27+
<artifactId>spring-boot-starter-web</artifactId>
28+
</dependency>
29+
30+
<dependency>
31+
<groupId>software.amazon.awssdk</groupId>
32+
<artifactId>bedrockruntime</artifactId>
33+
<version>2.30.35</version>
34+
</dependency>
35+
</dependencies>
36+
37+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.example.novareel;
5+
6+
public class GenerateVideoResponse {
7+
8+
private String executionArn;
9+
private String s3Bucket;
10+
private String status;
11+
12+
13+
public String getExecutionArn() {
14+
return executionArn;
15+
}
16+
17+
public void setExecutionArn(String executionArn) {
18+
this.executionArn = executionArn;
19+
}
20+
21+
public String getS3Bucket() {
22+
return s3Bucket;
23+
}
24+
25+
public void setS3Bucket(String s3Bucket) {
26+
this.s3Bucket = s3Bucket;
27+
}
28+
29+
public String getStatus() {
30+
return status;
31+
}
32+
33+
public void setStatus(String status) {
34+
this.status = status;
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.example.novareel;
5+
6+
import org.springframework.boot.WebApplicationType;
7+
import org.springframework.boot.autoconfigure.SpringBootApplication;
8+
import org.springframework.boot.builder.SpringApplicationBuilder;
9+
import org.springframework.context.ConfigurableApplicationContext;
10+
11+
@SpringBootApplication
12+
public class NovaReelDemo {
13+
14+
public static void main(String[] args) {
15+
16+
ConfigurableApplicationContext run = new SpringApplicationBuilder(NovaReelDemo.class)
17+
.web(WebApplicationType.SERVLET)
18+
.run(args);
19+
}
20+
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.example.novareel;
5+
6+
// snippet-start:[bedrock-runtime.java2.NovaReel.VideoGeneration]
7+
import org.springframework.stereotype.Service;
8+
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
9+
import software.amazon.awssdk.core.document.Document;
10+
import software.amazon.awssdk.regions.Region;
11+
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeAsyncClient;
12+
import software.amazon.awssdk.services.bedrockruntime.model.*;
13+
14+
import java.util.concurrent.CompletableFuture;
15+
16+
@Service
17+
public class VideoGenerationService {
18+
19+
public GenerateVideoResponse generateVideo(String prompt) {
20+
21+
// add S3 bucket you want to store your generated videos
22+
String s3Bucket = "s3://mygeneratedvidoenovatest";
23+
24+
25+
//Create json request as an instance of Document class
26+
Document novaRequest = prepareDocument(prompt);
27+
28+
// Create request
29+
StartAsyncInvokeRequest request = StartAsyncInvokeRequest.builder()
30+
.modelId("amazon.nova-reel-v1:0")
31+
.modelInput(novaRequest)
32+
.outputDataConfig(AsyncInvokeOutputDataConfig.builder()
33+
.s3OutputDataConfig(AsyncInvokeS3OutputDataConfig.builder().s3Uri(s3Bucket).build())
34+
.build())
35+
.build();
36+
37+
try (BedrockRuntimeAsyncClient bedrockClient = getBedrockRuntimeAsyncClient()) {
38+
CompletableFuture<StartAsyncInvokeResponse> startAsyncInvokeResponseCompletableFuture = bedrockClient.startAsyncInvoke(request);
39+
40+
//blocking operation to wait for the AWS API response
41+
StartAsyncInvokeResponse startAsyncInvokeResponse = startAsyncInvokeResponseCompletableFuture.get();
42+
System.out.println("invocation ARN: " + startAsyncInvokeResponse.invocationArn());
43+
44+
GenerateVideoResponse response = new GenerateVideoResponse();
45+
response.setStatus("inProgress");
46+
response.setExecutionArn(startAsyncInvokeResponse.invocationArn());
47+
48+
return response;
49+
} catch (Exception e) {
50+
System.out.println(e);
51+
throw new RuntimeException(e);
52+
}
53+
54+
}
55+
56+
public GenerateVideoResponse checkGenerationStatus(String invocationArn) {
57+
GenerateVideoResponse response = new GenerateVideoResponse();
58+
59+
try (BedrockRuntimeAsyncClient bedrockClient = getBedrockRuntimeAsyncClient()) {
60+
//creating async request to fetch status by invocation Arn
61+
GetAsyncInvokeRequest asyncRequest = GetAsyncInvokeRequest.builder().invocationArn(invocationArn).build();
62+
63+
CompletableFuture<GetAsyncInvokeResponse> asyncInvoke = bedrockClient.getAsyncInvoke(asyncRequest);
64+
65+
//blocking operation to wait for the AWS API response
66+
GetAsyncInvokeResponse asyncInvokeResponse = asyncInvoke.get();
67+
System.out.println("Invocation status =" + asyncInvokeResponse.statusAsString());
68+
69+
response.setExecutionArn(invocationArn);
70+
response.setStatus(asyncInvokeResponse.statusAsString());
71+
return response;
72+
} catch (Exception e) {
73+
e.printStackTrace();
74+
throw new RuntimeException(e);
75+
}
76+
77+
}
78+
79+
private static BedrockRuntimeAsyncClient getBedrockRuntimeAsyncClient() {
80+
BedrockRuntimeAsyncClient bedrockClient = BedrockRuntimeAsyncClient.builder()
81+
.region(Region.US_EAST_1)
82+
.credentialsProvider(ProfileCredentialsProvider.create())
83+
.build();
84+
return bedrockClient;
85+
}
86+
87+
private static Document prepareDocument(String prompt) {
88+
Document textToVideoParams = Document.mapBuilder()
89+
.putString("text", prompt)
90+
.build();
91+
92+
Document videoGenerationConfig = Document.mapBuilder()
93+
.putNumber("durationSeconds", 6)
94+
.putNumber("fps", 24)
95+
.putString("dimension", "1280x720")
96+
.build();
97+
98+
Document novaRequest = Document.mapBuilder()
99+
.putString("taskType", "TEXT_VIDEO")
100+
.putDocument("textToVideoParams", textToVideoParams)
101+
.putDocument("videoGenerationConfig", videoGenerationConfig)
102+
.build();
103+
return novaRequest;
104+
}
105+
}
106+
// snippet-end:[bedrock-runtime.java2.NovaReel.VideoGeneration]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package com.example.novareel;
5+
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
import org.springframework.http.MediaType;
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.annotation.PostMapping;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RequestParam;
12+
import org.springframework.web.bind.annotation.RestController;
13+
14+
@RestController
15+
@RequestMapping("/video")
16+
public class VideoGeneratorController {
17+
18+
@Autowired
19+
VideoGenerationService videoGenerationService;
20+
21+
@PostMapping(value = "/generate", produces = MediaType.APPLICATION_JSON_VALUE)
22+
public ResponseEntity<GenerateVideoResponse> generateVideo(@RequestParam String prompt) {
23+
return ResponseEntity.ok(videoGenerationService.generateVideo(prompt));
24+
}
25+
26+
@PostMapping(value = "/check", produces = MediaType.APPLICATION_JSON_VALUE)
27+
public ResponseEntity<GenerateVideoResponse> checkStatus(@RequestParam String invocationArn) {
28+
return ResponseEntity.ok(videoGenerationService.checkGenerationStatus(invocationArn));
29+
}
30+
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
spring:
2+
application:
3+
name: nova-reel-demo
4+

0 commit comments

Comments
 (0)