HarmonyOS 鸿蒙Next:arkweb组件中onInterceptRequest如何读本地视频并返回
HarmonyOS 鸿蒙Next:arkweb组件中onInterceptRequest如何读本地视频并返回
需求
webview中网页直接访问本地文档中的图片和视频并且显示出来
方法
目前是使用了arkweb组件中onInterceptRequest方法拦截请求,如果文件后缀是jpg那么就用arkts语言读取本地用户目录中的图片并且返回给response
图片目前是这么显示的,我把真实的路径直接放在file://后面,然后onInterceptRequest拦截的时候直接截掉file://就可以获得真实路径并且打开了。
chapterList[i]["page"]["img"] = 'file://' + path + '/img/' + prefix + "-" + pageName
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
目前这个成功了,效果可以,代码如下
.onInterceptRequest((event) => {
if (!event) {
return;
}
// 此处匹配自己想要加载的本地离线资源,进行资源拦截替换,绕过跨域
if (event.request.getRequestUrl().startsWith("file://")) {
let realPath: string = decodeURI(event.request.getRequestUrl().substring(7))
let stat = fs.statSync(realPath)
if (realPath.endsWith(".jpg")) {
let file = fs.openSync(realPath, fs.OpenMode.READ_ONLY)
let buf = new ArrayBuffer(stat.size);
fs.readSync(file.fd, buf)
fs.closeSync(file.fd)
let response = new WebResourceResponse();
response.setResponseData(buf);
response.setResponseEncoding('utf-8');
response.setResponseMimeType('image/jpg');
response.setResponseCode(200);
response.setReasonMessage('OK');
response.setResponseIsReady(true);
return response;
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
问题
但是视频却失败了,无法显示出来和调整播放进度,难道是我返回的response不对吗?还是说arkweb不支持播放本地视频?
else if (realPath.endsWith(".mp4")) {
let headers = event.request.getRequestHeader()
let ranges = Array<number>()
for (let header of headers) {
if (header.headerKey == "Range") {
let r = header.headerValue.split("=")[1]
ranges.push(Number(r.split("-")[0]))
}
}
let file = fs.openSync(realPath, fs.OpenMode.READ_ONLY)
let buf = new ArrayBuffer(10 * 1024 * 1024);
let redLen = fs.readSync(file.fd, buf, { offset: ranges[0] })
fs.closeSync(file.fd)
let response = new WebResourceResponse();
response.setResponseData(buf);
response.setResponseEncoding('utf-8');
response.setResponseMimeType('video/mp4');
response.setResponseCode(206);
response.setReasonMessage('Partial Content');
response.setResponseHeader([
{headerKey:"Accept-Ranges",headerValue:"bytes"},
{headerKey:"Content-Range",headerValue:`bytes ${ranges[0]}-${ranges[0]+redLen-1}/${stat.size-1}}`},
{headerKey:"Content-Length",headerValue:String(redLen)},
{headerKey:"Content-Type",headerValue:"video/mp4"}])
response.setResponseIsReady(true);
return response;
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 4px; right: 8px; font-size: 14px;">复制</button>
我抓取了一下request的数据,是一个带range的请求,所以我就把range当作读取文件的偏移量,然后读出数据并返回来
感谢,解决了,把下面这个编码注释掉就行了
response.setResponseEncoding('utf-8');
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
在HarmonyOS鸿蒙Next的arkweb组件中,onInterceptRequest
方法用于拦截并处理WebView中的资源请求。若你需要在该方法中读取本地视频并返回,可以按照以下步骤操作:
-
获取本地视频路径:首先,确保你已知晓本地视频的存储路径。这通常是一个文件系统中的路径,例如
/storage/emulated/0/DCIM/Camera/video.mp4
。 -
读取视频文件:使用Java的文件I/O操作读取视频文件内容。可以使用
FileInputStream
来读取文件内容到字节数组。 -
构造响应:在
onInterceptRequest
中,构造一个WebResourceResponse
对象。设置MIME类型为video/mp4
(或其他视频格式),编码为UTF-8
,并将视频内容的字节数组作为响应数据。 -
返回响应:最后,将构造好的
WebResourceResponse
对象返回给WebView,以处理该请求。
示例代码(简化版):
@Override
public WebResourceResponse onInterceptRequest(WebView view, WebResourceRequest request) {
String videoPath = "/path/to/video.mp4";
byte[] videoData = readFileToByteArray(videoPath);
WebResourceResponse response = new WebResourceResponse("video/mp4", "UTF-8", new ByteArrayInputStream(videoData));
return response;
}
注意:实际开发中需处理文件读取异常及资源释放等问题。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html