如何在Java中将byte[]格式图片转H.264并推送到AWS Kinesis Video流
Java实现byte[]图片转H.264并推送到AWS Kinesis Video流
核心依赖与工具
- AWS Kinesis Video Streams Producer SDK Java:官方提供的SDK,用于处理视频流的推送逻辑。
- JavaCV:基于FFmpeg/x264的Java封装库,简化H.264编码流程,适合将图片序列转为H.264视频流。
实现步骤
1. 依赖配置(Maven)
在pom.xml中添加以下依赖:
<!-- AWS Kinesis Video Producer SDK --> <dependency> <groupId>com.amazonaws</groupId> <artifactId>amazon-kinesis-video-streams-producer-sdk-java</artifactId> <version>1.14.0</version> </dependency> <!-- JavaCV 用于H.264编码 --> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv-platform</artifactId> <version>1.5.9</version> </dependency>
2. 将byte[]图片编码为H.264流
把byte[]格式的图片转为BufferedImage,再通过JavaCV的FFmpegFrameRecorder编码为Kinesis Video要求的H.264 NAL单元格式:
import org.bytedeco.javacv.*; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; // 初始化编码器(按需调整参数) private FFmpegFrameRecorder initRecorder(int width, int height) throws Exception { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputStream, width, height); recorder.setFormat("h264"); recorder.setFrameRate(25); // 帧率,控制视频播放速度 recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); recorder.setVideoBitrate(1000000); // 码率,平衡画质与带宽 recorder.start(); return recorder; } // 编码单张byte[]图片 public byte[] encodeImage(FFmpegFrameRecorder recorder, byte[] imageBytes) throws Exception { BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageBytes)); Frame frame = Java2DFrameConverter.convert(bufferedImage); recorder.record(frame); // 获取编码后的H.264字节流 return ((ByteArrayOutputStream) recorder.getOutputStream()).toByteArray(); }
3. 推送H.264流到Kinesis Video
使用AWS SDK获取PutMedia端点,将编码后的H.264数据推送到指定流:
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain; import com.amazonaws.services.kinesisvideo.AmazonKinesisVideo; import com.amazonaws.services.kinesisvideo.AmazonKinesisVideoClientBuilder; import com.amazonaws.services.kinesisvideo.model.*; import java.io.ByteArrayInputStream; // 初始化Kinesis Video客户端 private AmazonKinesisVideo initKinesisClient(String region) { return AmazonKinesisVideoClientBuilder.standard() .withCredentials(DefaultAWSCredentialsProviderChain.getInstance()) .withRegion(region) .build(); } // 推送H.264数据到流 public void pushToKinesis(AmazonKinesisVideo client, String streamName, byte[] h264Data) { // 获取PutMedia端点 GetDataEndpointRequest endpointReq = new GetDataEndpointRequest() .withStreamName(streamName) .withAPIName(APIName.PUT_MEDIA); String endpoint = client.getDataEndpoint(endpointReq).getDataEndpoint(); // 构建PutMedia请求并发送 PutMediaRequest putReq = new PutMediaRequest() .withStreamName(streamName) .withPayload(new ByteArrayInputStream(h264Data)) .withFragmentTimecodeType(FragmentTimecodeType.REALTIME); client.putMedia(putReq); }
关键注意事项
- 帧率控制:保持稳定的图片输入频率与编码器帧率一致,避免视频播放卡顿。
- 权限配置:确保AWS凭证拥有
kinesisvideo:PutMedia和kinesisvideo:GetDataEndpoint权限。 - NAL单元格式:Kinesis Video要求H.264数据以
0x00000001起始,JavaCV的默认输出符合该格式。 - 流式处理:持续获取图片时,建议使用线程池异步处理编码与推送,避免阻塞主线程。
内容的提问来源于stack exchange,提问作者Venkatrao Kulkarni
相关产品推荐
相关产品推荐

