diff --git a/.doc_gen/metadata/bedrock-runtime_metadata.yaml b/.doc_gen/metadata/bedrock-runtime_metadata.yaml index 90df1b274af..6309f654bba 100644 --- a/.doc_gen/metadata/bedrock-runtime_metadata.yaml +++ b/.doc_gen/metadata/bedrock-runtime_metadata.yaml @@ -1648,3 +1648,20 @@ bedrock-runtime_Scenario_InvokeModels: - php.example_code.bedrock-runtime.basics.scenario services: bedrock-runtime: {InvokeModel, InvokeModelWithResponseStream} + +bedrock-runtime_Scenario_GenerateVideos_NovaReel: + title: Generate videos from text prompts using &BR; and Nova-Reel + title_abbrev: "Generate videos from text prompts using &BR;" + synopsis: a Spring Boot app that generates videos from text prompts using &BR; and the Nova-Reel model. + category: Scenarios + languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/bedrock-runtime + excerpts: + - description: Generate videos from text prompts using &BR; and Nova-Reel. + snippet_tags: + - bedrock-runtime.java2.NovaReel.VideoGeneration + services: + bedrock-runtime: {StartAsyncInvoke, GetAsyncInvoke} diff --git a/javav2/usecases/video_generation_bedrock_nova_reel/README.md b/javav2/usecases/video_generation_bedrock_nova_reel/README.md new file mode 100644 index 00000000000..c7ddda9383d --- /dev/null +++ b/javav2/usecases/video_generation_bedrock_nova_reel/README.md @@ -0,0 +1,110 @@ +# NovaReel Video Generation Service + +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. + +## Overview + +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. + +It consists of: +- A REST controller for handling API requests +- A service class to interact with Amazon Bedrock +- A response model for encapsulating result data + +## Project Structure +![](images/structure.png) +- **NovaReelDemo.java** Main class to bootstrap the Spring Boot app +- **GenerateVideoResponse.java** Response DTO with fields: executionArn, s3Bucket, status +- **VideoGenerationService.java** Service for interacting with Amazon Bedrock +- **VideoGeneratorController.java** REST controller exposing /video endpoints + +## Functionality + +### 1. Generate Video +**Endpoint:** POST /video/generate +**Query Param:** prompt (string) +**Description:** +- Takes a text prompt +- Sends an async request to `amazon.nova-reel-v1:0` using Bedrock +- The generated video will be stored in the specified S3 bucket in 3-5 mins +- Returns the executionArn + +### 2. Check Status +**Endpoint:** POST /video/check +**Query Param:** invocationArn (string) +**Description:** +- Checks the generation status of a video using invocationArn +- Returns the current status + +## Configuration + +### Prerequisites + +- AWS account with access to Amazon Bedrock +- AWS credentials configured via named profile (e.g. `~/.aws/credentials`) +- A valid S3 bucket for output (currently hardcoded) + +### Modify S3 Bucket + +In `VideoGenerationService.java`, update the following line: +`String s3Bucket = "s3://add_your_bucket_here";` +Replace with your own S3 bucket URI where videos should be saved. + +### AWS Credentials + +By default, credentials are loaded from a named profile using: +`ProfileCredentialsProvider.create()` +Make sure you have the profile set in your `~/.aws/config` or override it as needed. + +### IAM Permissions +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 +The minimum action permissions required to execute this application are: + +``` +bedrock:InvokeModel +s3:PutObject +bedrock:GetAsyncInvoke +bedrock:ListAsyncInvokes +``` + + +## How to Run + +1. Clone the repo +2. Update the S3 bucket in `VideoGenerationService.java` +3. Set up AWS credentials +4. Build and run the Spring Boot application: + `./mvnw spring-boot:run` +5. Use an API client (e.g. Postman or curl) to interact with the endpoints + +## Example Requests + +### Generate Video +``` +curl -X POST "http://localhost:8080/video/generate?prompt=A cat surfing on a pizza in space" +``` + +### Check Status +``` +curl -X POST "http://localhost:8080/video/check?invocationArn=" +``` +when status is Completed - video generated and stored in S3 bucket + +## Dependencies + +- Spring Boot Web +- AWS SDK v2 (Bedrock Runtime) +- Jackson / JSON +- Maven or Gradle for build + + +## Future Improvements + +- Make S3 bucket configurable via `application.yml` +- Add status polling endpoint that waits until generation is complete +- Integrate with frontend or S3 browser to retrieve the generated video + +## Additional Materials + +- [Amazon Bedrock Overview](https://aws.amazon.com/bedrock/) +- [Amazon Nova Reel - AWS AI Service Cards](https://docs.aws.amazon.com/ai/responsible-ai/nova-reel/overview.html) diff --git a/javav2/usecases/video_generation_bedrock_nova_reel/images/structure.png b/javav2/usecases/video_generation_bedrock_nova_reel/images/structure.png new file mode 100644 index 00000000000..fa40a370bda Binary files /dev/null and b/javav2/usecases/video_generation_bedrock_nova_reel/images/structure.png differ diff --git a/javav2/usecases/video_generation_bedrock_nova_reel/pom.xml b/javav2/usecases/video_generation_bedrock_nova_reel/pom.xml new file mode 100644 index 00000000000..81d92b1ed51 --- /dev/null +++ b/javav2/usecases/video_generation_bedrock_nova_reel/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.4.1 + + + + com.example + nova-reel-test + 1.0-SNAPSHOT + + + 17 + 17 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + software.amazon.awssdk + bedrockruntime + 2.30.35 + + + + \ No newline at end of file diff --git a/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/GenerateVideoResponse.java b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/GenerateVideoResponse.java new file mode 100644 index 00000000000..587436d54ef --- /dev/null +++ b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/GenerateVideoResponse.java @@ -0,0 +1,36 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.novareel; + +public class GenerateVideoResponse { + + private String executionArn; + private String s3Bucket; + private String status; + + + public String getExecutionArn() { + return executionArn; + } + + public void setExecutionArn(String executionArn) { + this.executionArn = executionArn; + } + + public String getS3Bucket() { + return s3Bucket; + } + + public void setS3Bucket(String s3Bucket) { + this.s3Bucket = s3Bucket; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/NovaReelDemo.java b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/NovaReelDemo.java new file mode 100644 index 00000000000..3d1165551f9 --- /dev/null +++ b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/NovaReelDemo.java @@ -0,0 +1,21 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.novareel; + +import org.springframework.boot.WebApplicationType; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.context.ConfigurableApplicationContext; + +@SpringBootApplication +public class NovaReelDemo { + + public static void main(String[] args) { + + ConfigurableApplicationContext run = new SpringApplicationBuilder(NovaReelDemo.class) + .web(WebApplicationType.SERVLET) + .run(args); + } + +} diff --git a/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/VideoGenerationService.java b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/VideoGenerationService.java new file mode 100644 index 00000000000..b4e85d9603f --- /dev/null +++ b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/VideoGenerationService.java @@ -0,0 +1,106 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.novareel; + +// snippet-start:[bedrock-runtime.java2.NovaReel.VideoGeneration] +import org.springframework.stereotype.Service; +import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; +import software.amazon.awssdk.core.document.Document; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeAsyncClient; +import software.amazon.awssdk.services.bedrockruntime.model.*; + +import java.util.concurrent.CompletableFuture; + +@Service +public class VideoGenerationService { + + public GenerateVideoResponse generateVideo(String prompt) { + + // add S3 bucket you want to store your generated videos + String s3Bucket = "s3://mygeneratedvidoenovatest"; + + + //Create json request as an instance of Document class + Document novaRequest = prepareDocument(prompt); + + // Create request + StartAsyncInvokeRequest request = StartAsyncInvokeRequest.builder() + .modelId("amazon.nova-reel-v1:0") + .modelInput(novaRequest) + .outputDataConfig(AsyncInvokeOutputDataConfig.builder() + .s3OutputDataConfig(AsyncInvokeS3OutputDataConfig.builder().s3Uri(s3Bucket).build()) + .build()) + .build(); + + try (BedrockRuntimeAsyncClient bedrockClient = getBedrockRuntimeAsyncClient()) { + CompletableFuture startAsyncInvokeResponseCompletableFuture = bedrockClient.startAsyncInvoke(request); + + //blocking operation to wait for the AWS API response + StartAsyncInvokeResponse startAsyncInvokeResponse = startAsyncInvokeResponseCompletableFuture.get(); + System.out.println("invocation ARN: " + startAsyncInvokeResponse.invocationArn()); + + GenerateVideoResponse response = new GenerateVideoResponse(); + response.setStatus("inProgress"); + response.setExecutionArn(startAsyncInvokeResponse.invocationArn()); + + return response; + } catch (Exception e) { + System.out.println(e); + throw new RuntimeException(e); + } + + } + + public GenerateVideoResponse checkGenerationStatus(String invocationArn) { + GenerateVideoResponse response = new GenerateVideoResponse(); + + try (BedrockRuntimeAsyncClient bedrockClient = getBedrockRuntimeAsyncClient()) { + //creating async request to fetch status by invocation Arn + GetAsyncInvokeRequest asyncRequest = GetAsyncInvokeRequest.builder().invocationArn(invocationArn).build(); + + CompletableFuture asyncInvoke = bedrockClient.getAsyncInvoke(asyncRequest); + + //blocking operation to wait for the AWS API response + GetAsyncInvokeResponse asyncInvokeResponse = asyncInvoke.get(); + System.out.println("Invocation status =" + asyncInvokeResponse.statusAsString()); + + response.setExecutionArn(invocationArn); + response.setStatus(asyncInvokeResponse.statusAsString()); + return response; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + + } + + private static BedrockRuntimeAsyncClient getBedrockRuntimeAsyncClient() { + BedrockRuntimeAsyncClient bedrockClient = BedrockRuntimeAsyncClient.builder() + .region(Region.US_EAST_1) + .credentialsProvider(ProfileCredentialsProvider.create()) + .build(); + return bedrockClient; + } + + private static Document prepareDocument(String prompt) { + Document textToVideoParams = Document.mapBuilder() + .putString("text", prompt) + .build(); + + Document videoGenerationConfig = Document.mapBuilder() + .putNumber("durationSeconds", 6) + .putNumber("fps", 24) + .putString("dimension", "1280x720") + .build(); + + Document novaRequest = Document.mapBuilder() + .putString("taskType", "TEXT_VIDEO") + .putDocument("textToVideoParams", textToVideoParams) + .putDocument("videoGenerationConfig", videoGenerationConfig) + .build(); + return novaRequest; + } +} +// snippet-end:[bedrock-runtime.java2.NovaReel.VideoGeneration] diff --git a/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/VideoGeneratorController.java b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/VideoGeneratorController.java new file mode 100644 index 00000000000..17f15a46bbb --- /dev/null +++ b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/java/com/example/novareel/VideoGeneratorController.java @@ -0,0 +1,31 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.novareel; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/video") +public class VideoGeneratorController { + + @Autowired + VideoGenerationService videoGenerationService; + + @PostMapping(value = "/generate", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity generateVideo(@RequestParam String prompt) { + return ResponseEntity.ok(videoGenerationService.generateVideo(prompt)); + } + + @PostMapping(value = "/check", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity checkStatus(@RequestParam String invocationArn) { + return ResponseEntity.ok(videoGenerationService.checkGenerationStatus(invocationArn)); + } + +} diff --git a/javav2/usecases/video_generation_bedrock_nova_reel/src/main/resources/application.yaml b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/resources/application.yaml new file mode 100644 index 00000000000..16af88fa144 --- /dev/null +++ b/javav2/usecases/video_generation_bedrock_nova_reel/src/main/resources/application.yaml @@ -0,0 +1,4 @@ +spring: + application: + name: nova-reel-demo +