【官方总结】HarmonyOS鸿蒙Next应用开发FAQ汇总-媒体
【官方总结】HarmonyOS鸿蒙Next应用开发FAQ汇总-媒体
1.HarmonyOS如何使用ets访问系统图库(eTS)(API 8)
// 导入模块
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import featureAbility from '@ohos.ability.featureAbility';
// 创建媒体数据管理器的实例
var mediaLibraryInstance = mediaLibrary.getMediaLibrary();
// 启动媒体选择界面
let option = {
type : "image",
count : 5
};
mediaLibraryInstance.startMediaSelect(option).then(value => {
console.log("Media resources selected.");
this.imageArr = value;
}).catch(err => {
console.log("An error occurred when selecting media resources.");
});
2.HarmonyOS使用JS框架读取本地音乐还需要用到音乐在设备上的绝对路径?有点麻烦,有案例吗(eTS)(API 8)
3.HarmonyOS如何使用JS实现音频录制(JS)(API 8)
媒体管理API提供了音频播放、音频录制等相关能力。请参考: https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-media-0000001103383404
4.HarmonyOS中JS媒体组件camera拍照成功后,如何将图片保存到手机相册(JS)(API8)
拍照成功后,回调函数会返回图片的uri,使用媒体数据管理提供的storeMediaAsset()可以将图片保存到本地相册,请参考: https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-medialibrary-0000001168747257#section964512672913
5. SurfaceProvider如何加载resource下的图片资源(Java)(API 6)
SurfaceProvider暂时不能直接加载resource下的图片资源。以下提供两种加载resource下图片的方法:
方法一
Image image = (Image) findComponentById(ResourceTable.Id_image);
PixelMapElement element = new PixelMapElement(image.getPixelMap());
SurfaceProvider surfaceProvider = new SurfaceProvider(this);
surfaceProvider.setBackground(element);
PixelMapElement backgroundElement = (PixelMapElement) surfaceProvider.getBackgroundElement();
PixelMap pixelMap = backgroundElement.getPixelMap();
方法二
private static final int DESIRE_WIDTH = 100;
private static final int DESIRE_HEIGHT = 100;
...
InputStream source = null;
ImageSource imageSource = null;
try {
source = this.getResourceManager().getResource(ResourceTable.Media_a);
imageSource = ImageSource.create(source, null);
ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
decodingOpts.desiredSize = new Size(DESIRE_WIDTH , DESIRE_HEIGHT);
PixelMap pixelmap = imageSource.createPixelmap(decodingOpts);
} catch (IOException | NotExistException e) {
……
} finally {
try {
source.close();
} catch (IOException e) {
……
}
}
6. HarmonyOS如何把resource图片转成URI(Java)(API 6)
String path = null;
try {
path = getResourceManager().getMediaPath(ResourceTable.xxx);
} catch (IOException e) {
HiLog.error(LABEL_LOG,e.getMessage());
} catch (NotExistException e) {
HiLog.error(LABEL_LOG,e.getMessage());
} catch (WrongTypeException e) {
HiLog.error(LABEL_LOG,e.getMessage());
}
Uri uri = Uri.parse(path);
7. HarmonyOS中如何实现触摸缩放图片(Java)(API 6)
// 开始的参考点以两个触摸点的中心为准
Matrix matrix = new Matrix();
float scale = endDis / startDis;
matrix.setMatrix(currentMatrix);
// 参数1,2指定在x,y轴的放大倍数;参数3,4为缩放参考点的x,y轴坐标
matrix.postScale(scale, scale, midPoint.getX(), midPoint.getY());
// 图片缩放
image.addDrawTask((component,canvas)->
{
// 通过矩阵实现缩放
canvas.setMatrix(matrix);
});
8. 参看AudioDeviceDescriptor的API编写代码播放一段mp3音频总是没有声音(Java)(API 6)
AudioDeviceDescriptor不是支持音视频播放的接口类。目前HarmonyOS提供的可播放mp3格式的sdk接口是harmonyos.media.player.Player。
示例代码如下:
try (FileInputStream in = new FileInputStream(new File(PLAYER_TEST_FILE))) {
FileDescriptor fd = in.getFD();
Source source = new Source(fd);
Player impl = new Player(this);
impl.setSource(source);
impl.prepare();
impl.play();
} catch (IOException e) {
...
}
具体使用方法请参考: Player API参考
9. 如何持续获取相机的帧数据(Java)(API 6)
1.在相机配置时调用 setFrameStateCallback(FrameStateCallback callback, EventHandler handler)方法设置帧回调。 2.通过camera.triggerLoopingCapture(FrameConfig)方法实现循环帧捕获。
具体使用方法请参考: 相机设备开发指导
10. 如何使用AudioRenderer的参数(Java)(API 6)
参照如下代码,配置AudioStreamInfo :
配置AudioStreamInfo
// 44.1kHz
final int RATE = 44100;
AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder()
// 采样率
.sampleRate(RATE)
// 混音
.audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_MAY_DUCK)
// 16-bit PCM
.encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT)
// 双声道输出
.channelMask(AudioStreamInfo.ChannelMask.CHANNEL_OUT_STEREO)
// 媒体类音频
.streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_MEDIA)
.build();
配置AudioRendererInfo
final int BUFFER_SIZE = 1024;
AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder()
.audioStreamInfo(audioStreamInfo)
// pcm格式的输出流
.audioStreamOutputFlag(
AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_DIRECT_PCM)
.bufferSizeInBytes(BUFFER_SIZE)
// false表示分段传输buffer并播放,true表示整个音频流一次性传输到HAL层播放
.isOffload(false)
.build();
初始化AudioRenderer
AudioRenderer audioRenderer = new AudioRenderer(audioRendererInfo,AudioRenderer.PlayMode.MODE_STREAM);
文件读取
final int BUFFER_SIZE = 1024;
final int FLAG_INT = -1;
File file = new File("test.wav");
FileInputStream soundInputStream;
int bufSize = audioRenderer.getBufferFrameSize();
byte[] buffer = new byte[BUFFER_SIZE];
int len;
try {
soundInputStream = new FileInputStream(file);
audioRenderer.start();
while ((len = soundInputStream.read(buffer, 0, buffer.length)) != FLAG_INT) {
audioRenderer.write(buffer, 0, buffer.length);
}
soundInputStream.close();
} catch (IOException e) {
HiLog.error(LABEL_LOG, e.getMessage());
}
11. 音频播放,使用文件输出流写数据后,发现文件写后结果总是Null(Java)(API 6)
原因为getGlobalTaskDispatcher的asyncDispatch方法异步导致,采用getGlobalTaskDispatcher的syncDispatch方法同步操作。
12. CameraId的获取是否可以理解为本机可以获取分布式设备支持的camera,还是只是可以获取自身设备的camera(Java)(API 6)
CameraId指的是逻辑相机的Id,与分布式没有关系,不能获取远端CameraId。
物理相机是独立的实体摄像头设备。物理相机Id是用于标志每个物理摄像头的唯一字串。
逻辑相机是多个物理相机组合出来的抽象设备,逻辑相机通过同时控制多个物理相机设备来完成相机某些功能,如大光圈、变焦等功能。多个物理摄像头合在一起组成了一个唯一的字串,此字串即逻辑相机Id。
13. PixelMap如何保存成本地图片文件(Java)(API 6)
如下代码提供将PixelMap对象转换成new.jpeg图片并保存的例子,请参考:
private static final HiLogLabel LABEL_LOG = new HiLogLabel(0, 0, "LogUtil");
private static final String LOG_FORMAT = "%{public}s: %{public}s";
ImagePacker imagePacker = ImagePacker.create();
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "new.jpeg");
FileOutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
} catch (FileNotFoundException e) {
HiLog.info(LABEL_LOG, LOG_FORMAT, "", "out put file path is incorrect");
}
ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
packingOptions.format = "image/jpeg";
packingOptions.quality = 100;// 设置图片质量
boolean result = imagePacker.initializePacking(outputStream, packingOptions);
result = imagePacker.addImage(pixelMap);
long dataSize = imagePacker.finalizePacking();
开发者文档请参考如下链接: https://developer.harmonyos.com/cn/docs/documentation/doc-guides/media-image-encoding-0000001050994971
14. 如何获取视频的第一帧作为视频的封面(Java)(API 6)
1.创建媒体数据管理AVMetadataHelper对象,可以通过setSource设置要读取的媒体文件,如果不设置或设置不正确,则无法进行后续操作。
AVMetadataHelper avMetadataHelper = new AVMetadataHelper ();
avMetadataHelper.setSource("/data/data/com.huawei.multimedia/video.mov");
2.指定获取帧数据的选项,以及获取帧的时间,获取媒体源的帧数据。
PixelMap pixelMap = avMetadataHelper.fetchVideoPixelMapByTime(1000L, 0x00);
3.获取到PixelMap对象后,调用release()函数释放读取的媒体资源。
avMetadataHelper.release();
15. 调用相机预览时黑屏如何解决(Java)(API 6)
在设置surfaceProvider组件属性时增加如下代码:
getWindow().setTransparent(true);
surfaceProvider.pinToZTop(false);
16. JS API中如何播放音频,使用无效(Java)(API 6)
使用video可以实现音频播放,注意资源文件引入路径是否正确:
<video src=""></video>
17. HarmonyOS相机如何进入单帧捕获生成图像回调(Java)(API 6)
1.创建ImageReceiver对象并绑定监听。
private static final int CAPACITY = 5;
private void takePictureInit() {
List<Size> pictureSizes = cameraAbility.getSupportedSizes(ImageFormat.JPEG); // 获取拍照支持分辨率列表
pictureSize = getpictureSize(pictureSizes); // 根据拍照要求选择合适的分辨率
imageReceiver = ImageReceiver.create(Math.max(pictureSize.width, pictureSize.height),
Math.min(pictureSize.width, pictureSize.height),
ImageFormat.JPEG, CAPACITY); // 创建ImageReceiver对象,注意create函数中宽度要大于高度;5为最大支持的图像数,请根据实际设置。
imageReceiver.setImageArrivalListener(imageArrivalListener);
}
2.触发对应事件。
cameraDevice.triggerSingleCapture(pictureFrameConfig);
相机开发请参考: https://developer.huawei.com/consumer/cn/codelabsPortal/carddetails/HarmonyOS-DistributedCamera
18. 如何用canvas画出旋转的图片(Java)(API 6)
通过canvas的rotate方法实现图片旋转动画:
1.将图片转换成PixelMap
public PixelMap getPixelMap() {
InputStream drawableInputStream = null;
PixelMap pixelMap = null;
try {
drawableInputStream = this.getResourceManager().getResource(ResourceTable.Media_delete);
ImageSource imageSource = ImageSource.create(drawableInputStream, new ImageSource.SourceOptions());
ImageSource.DecodingOptions options = new ImageSource.DecodingOptions();
pixelMap = imageSource.createPixelmap(options);
return pixelMap;
} catch (IOException | NotExistException exception) {
HiLog.error(LABEL_LOG, "IOException | NotExistException", exception.getMessage());
} finally {
if (drawableInputStream != null) {
try {
drawableInputStream.close();
} catch (IOException e) {
HiLog.error(LABEL_LOG, "IOException", e.getMessage());
}
}
}
return pixelMap;
}
2.在onDraw方法中画图片。
Component componentById = findComponentById(ResourceTable.Id_main_layout);
componentById.addDrawTask(new Component.DrawTask() {
@Override
public void onDraw(Component component, Canvas canvas)
{
PixelMap pixelMap = getPixelMap();
PixelMapHolder pmh = new PixelMapHolder(pixelMap);
// 以(x,y)为中心点,将画布旋转degree角度
canvas.rotate(degree, x, y);
canvas.drawPixelMapHolder(
pmh,
0,
0,
new Paint());
}
});
3.如果想让图片持续旋转,实现旋转动画,可以持续改变degree的值,然后调用invalidate()方法。
19. HarmonyOS相机如何获取和设置曝光值(Java)(API 6)
相机可以获取和设置曝光模式,不能直接获取到值。
getSupportedAeMode(),获取当前相机支持的自动曝光模式。
setAeMode(int aeMode, Rect rect),配置曝光模式。
20. 如何一直开启闪光灯(Java)(API 6)
将闪光灯设置为FLASH_ALWAYS_OPEN模式,闪光灯会一直开启,示例代码如下:
private FrameConfig.Builder framePreviewConfigBuilder;
private Camera qrCamera;
// 打开闪光灯
public void openFlashlight() {
framePreviewConfigBuilder.setFlashMode(Metadata.FlashMode.FLASH_ALWAYS_OPEN);
qrCamera.triggerLoopingCapture(framePreviewConfigBuilder.build());
}
21. 如何使播放器支持播放网络视频(Java)(API 6)
1.访问外网,需要在config.json中添加INTERNET权限,如下所示:
"reqPermissions": [
{
"name": "ohos.permission.INTERNET"
}
]
2.鸿蒙的默认是https访问模式,如果您的请求网址是http开头的,请在config.json文件中的deviceConfig下,添加如下设置:
"deviceConfig": {
"default": {
"network": {
"cleartextTraffic": true
}
}
},
3.初始化SurfaceProvider及Player:
// 网络地址
private String url ="";
private SurfaceProvider surfaceProvider;
private Player player;
private void initSurfaceProviderPlayer() {
surfaceProvider= (SurfaceProvider) findComponentById(ResourceTable.Id_surfaceProvider);
surfaceProvider.pinToZTop(true);// 不设置这个 画面不显示;
player=new Player(getContext());
surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
@Override
public void surfaceCreated(SurfaceOps surfaceOps) {
// 这里设置的播放源为网络地址,
player.setSource(new Source(url));
player.setVideoSurface(surfaceOps.getSurface());
player.prepare();
}
@Override
public void surfaceChanged(SurfaceOps holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceOps surfaceOps) {
}
});
}
4.调用play()方法播放:
if (player != null) {
player.play();
}
22. 如何将PixelMap转化为Byte数组(Java)(API 6)
参考如下代码:
private PixelMap readLogoPixelmap(Context context) {
PixelMap logoPixelMap = null;
try {
ImageSource logoSource = ImageSource.create(
context.getResourceManager().getResource(ResourceTable.Media_icon),
null);
ImageSource.DecodingOptions opts = new ImageSource.DecodingOptions();
opts.editable = true;
logoPixelMap = logoSource.createPixelmap(opts);
} catch (IOException | NotExistException e) {
HiLog.info(LABEL_LOG, "read error");
}
return logoPixelMap;
}
// 获取PixelMap图像,并写入ByteBuffer中。
PixelMap pixelMap = readLogoPixelmap(context);
Size size = pixelMap.getImageInfo().size;
ByteBuffer byteBuffer = ByteBuffer.allocate(size.width * size.height * 4);
pixelMap.readPixels(byteBuffer);
byteBuffer.flip();
23. Player开发视频播放,如何实现重播功能(Java)(API 6)
1.准备播放地址:
private String url ="";
2.在xml布局添加SurfaceProvider:
<SurfaceProvider
ohos:height="match_parent"
ohos:width="match_parent"
ohos:id="$+id:surfaceProvider"
/>
3.初始化SurfaceProvider及Player:
private SurfaceProvider surfaceProvider;
private Player player;
private void initSurfaceProviderPlayer() {
surfaceProvider= (SurfaceProvider) findComponentById(ResourceTable.Id_surfaceProvider);
surfaceProvider.pinToZTop(true);// 不设置这个 画面不显示;
player=new Player(getContext());
surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
@Override
public void surfaceCreated(SurfaceOps surfaceOps) {
// 这里设置的播放源为网络地址,
player.setSource(new Source(url));
player.setVideoSurface(surfaceOps.getSurface());
player.prepare();
}
@Override
public void surfaceChanged(SurfaceOps holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceOps surfaceOps) {
}
});
// 设置播放回调接口
player.setPlayerCallback(new Player.IPlayerCallback() {
//这里省略其他实现方法
//这个方法在视频播放后回调,执行play()实现重播;
@Override
public void onPlayBackComplete() {
if (player != null) {
player.play();
}
}
});
}
3.点击按钮实现播放(按钮控件自行在xml添加):
findComponentById(ResourceTable.Id_play).setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
if (player != null) {
player.play();
}
}
});
24. HarmonyOS如何实现图片切换动画(Java)(API 6)
使用属性动画AnimatorProperty实现图片切换动画,参考以下代码:
Image image;
AnimatorProperty animator = image.createAnimatorProperty();
animator.moveFromX(50).moveToX(1000).rotate(180).alpha(0).setDuration(2500).setDelay(500).setLoopedCount(5);
animator.start();
//可以使用setTarget()改变关联的Component对象。
Image image2;
animator.setTarget(image2);
25. 如何获取图片的宽高(Java)(API 6)
请参考如下代码实现:
public class MainAbilitySlice extends AbilitySlice {
private PixelMap pixelMap;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
Size size = pixelMap.getImageInfo().size;
int width = size.width;
int height = size.height;
}
}
26.获取视频截图报错(Java)(API 6)
setSource(FileDescriptor fd) 这种公共目录资源不能直接访问,可以通过数据库进行访问,参考如下代码:
Context context = getContext();
Uri myUri = AVStorage.Video.Media.EXTERNAL_DATA_ABILITY_URI;
DataAbilityHelper helper = DataAbilityHelper.creator(context);
try {
DataAbilityPredicates dataAbilityPredicates = new DataAbilityPredicates("_id>?");
dataAbilityPredicates.setWhereArgs(Arrays.asList("0"));
ResultSet result = helper.query(myUri, null, null);
if (result == null) {
return;
}
while (result.goToNextRow()) {
int anInt = result.getInt(result.getColumnIndexForName(AVStorage.Video.Media.ID));
Uri uri = Uri.appendEncodedPathToUri(AVStorage.Video.Media.EXTERNAL_DATA_ABILITY_URI,
String.valueOf(anInt));
FileDescriptor fd = helper.openFile(uri, "r");
AVMetadataHelper avMetadataHelper = new AVMetadataHelper();
avMetadataHelper.setSource(fd);
avMetadataHelper.release();
}
} catch (DataAbilityRemoteException | FileNotFoundException e) {
// ...
}
27.HarmonyOS相机纵向、横向拉伸问题该如何处理(Java)(API 6)
自定义相机预览变形需要在surfaceProvider回调surfaceCreated时设置尺寸,以当前控件宽高为准,如以下代码所示:
surfaceCreated(SurfaceOps surfaceOps) {
surfaceOps.setFixedSize(getHeight(), getWidth());
...
}
竖屏拍照可以设置照片角度,如以下代码所示:
// 调用拍照
public void capture() {
// 获取拍照配置模板
FrameConfig.Builder pictureFrameConfigBuilder =
cameraDevice.getFrameConfigBuilder(Camera.FrameConfigType.FRAME_CONFIG_PICTURE);
// 配置拍照surface
pictureFrameConfigBuilder.addSurface(imageReceiver.getRecevingSurface());
// 设置照片角度
pictureFrameConfigBuilder.setImageRotation(90);
try {
// 启动拍照
cameraDevice.triggerSingleCapture(pictureFrameConfigBuilder.build());
} catch (Exception e) {
e.printStackTrace();
}
}
请问楼主player的onPlayerBackComplete回调经常不走,偶然会走是怎么回事呢
更多关于【官方总结】HarmonyOS鸿蒙Next应用开发FAQ汇总-媒体的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
学习收藏了,感谢分享!
学习收藏了,感谢分享!
非常感谢楼主的分享!
HarmonyOS鸿蒙Next应用开发中,媒体相关的FAQ主要涉及音频、视频、图像等多媒体功能的实现与优化。以下是一些常见问题及解答:
-
如何实现音频播放?
- 使用
AudioPlayer
类进行音频播放,支持本地和网络音频资源。通过prepare()
、play()
、pause()
、stop()
等方法控制播放状态。
- 使用
-
如何实现视频播放?
- 使用
VideoPlayer
类进行视频播放,支持本地和网络视频资源。通过prepare()
、start()
、pause()
、stop()
等方法控制播放状态。
- 使用
-
如何实现图像加载与显示?
- 使用
Image
组件加载和显示图像,支持本地和网络图像资源。通过src
属性指定图像源,width
和height
属性设置图像尺寸。
- 使用
-
如何实现音频录制?
- 使用
AudioRecorder
类进行音频录制,支持设置采样率、声道数、编码格式等参数。通过start()
、pause()
、resume()
、stop()
等方法控制录制过程。
- 使用
-
如何实现视频录制?
- 使用
VideoRecorder
类进行视频录制,支持设置分辨率、帧率、编码格式等参数。通过start()
、pause()
、resume()
、stop()
等方法控制录制过程。
- 使用
-
如何实现图像处理?
- 使用
Image
类进行图像处理,支持裁剪、旋转、缩放、滤镜等操作。通过getPixelMap()
获取图像像素数据,进行进一步处理。
- 使用
-
如何实现多媒体资源管理?
- 使用
MediaLibrary
类进行多媒体资源管理,支持查询、添加、删除、修改等操作。通过getMediaAssets()
获取多媒体资源列表。
- 使用
-
如何实现多媒体事件监听?
- 使用
MediaEventListener
类进行多媒体事件监听,支持播放完成、播放错误、播放状态变化等事件。通过onEvent()
方法处理事件。
- 使用
-
如何实现多媒体资源缓存?
- 使用
MediaCache
类进行多媒体资源缓存,支持设置缓存大小、缓存路径等参数。通过put()
、get()
、remove()
等方法管理缓存。
- 使用
-
如何实现多媒体资源加密?
- 使用
MediaEncryptor
类进行多媒体资源加密,支持设置加密算法、密钥等参数。通过encrypt()
、decrypt()
等方法进行加密解密操作。
- 使用
以上是HarmonyOS鸿蒙Next应用开发中媒体相关的常见问题及解答。
HarmonyOS鸿蒙Next应用开发中,媒体相关FAQ主要涉及音频、视频、图像处理等功能的实现与优化。开发者常遇到音频播放延迟、视频编解码兼容性、图像渲染性能等问题。建议使用系统提供的MediaPlayer、VideoView等组件,并遵循官方文档进行参数配置与性能调优。同时,关注设备硬件差异,确保应用在不同设备上的兼容性与稳定性。