HarmonyOS 鸿蒙Next:arkweb组件中onInterceptRequest如何读本地视频并返回

发布于 1周前 作者 gougou168 最后一次编辑是 5天前 来自 鸿蒙OS

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当作读取文件的偏移量,然后读出数据并返回来

2 回复

感谢,解决了,把下面这个编码注释掉就行了

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中的资源请求。若你需要在该方法中读取本地视频并返回,可以按照以下步骤操作:

  1. 获取本地视频路径:首先,确保你已知晓本地视频的存储路径。这通常是一个文件系统中的路径,例如/storage/emulated/0/DCIM/Camera/video.mp4

  2. 读取视频文件:使用Java的文件I/O操作读取视频文件内容。可以使用FileInputStream来读取文件内容到字节数组。

  3. 构造响应:在onInterceptRequest中,构造一个WebResourceResponse对象。设置MIME类型为video/mp4(或其他视频格式),编码为UTF-8,并将视频内容的字节数组作为响应数据。

  4. 返回响应:最后,将构造好的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

回到顶部