代码之家  ›  专栏  ›  技术社区  ›  Searene

Android:如何在WebView中加载本地压缩音频文件

  •  0
  • Searene  · 技术社区  · 6 年前

    <audio controls>
      <source src="zip://resource?fileName=apple.wav" type="audio/wav">
    </audio>
    

    apple.wav 存储在本地zip文件中。我想要的是,当用户单击音频组件上的“播放”按钮时,WebView将尝试从zip文件加载wav音频。目前我所尝试的是创建一个本地WebViewClient,如下所示。

    public class MyWebViewClient extends WebViewClient {
        @Override
        public WebResourceResponse shouldInterceptRequest(final WebView view, String url) {
            if (url.startsWith("zip://resource")) {
                Uri uri = Uri.parse(url);
                String fileName = uri.getQueryParameter("fileName");
                byte[] resourceContents = getResource(fileName);
                WebResourceResponse webResourceResponse = new WebResourceResponse("audio/wav",
                        "UTF-8", new ByteArrayInputStream(resourceContents));
                Map<String, String> responseHeaders = new HashMap<>();
    
                responseHeaders.put("Content-Type", "audio/wav");
                webResourceResponse.setResponseHeaders(responseHeaders);
                return webResourceResponse;
            } else {
                return super.shouldInterceptRequest(view, url);
            }
        }
        private byte[] getResource(String resourceName) {
            // read the audio contents from the pre-determined zip file
        }
    }
    

    然后将其分配给WebView。

    WebView webView = findViewById(R.id.webview);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setWebViewClient(new MyWebViewClient());
    

    但没用。当我点击“播放”按钮时,什么也没发生。我在网上搜索了很久,唯一相关的问题是 this one 但是这个问题的答案并不优雅,它涉及到修改HTML和将音频文件写入sdcard。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Searene    6 年前

    我终于用WebInterface解决了这个问题,这也不是一个很好的解决方案,音频文件在播放前必须写入磁盘。但成功了。

    这是我使用的HTML:

    <button onclick='Audio.playAudio()' />
    

    import android.media.MediaPlayer;
    import android.webkit.JavascriptInterface;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class PlayAudioWebInterface {
        @JavascriptInterface
        public void playAudio() {
            try {
                MediaPlayer mp = new MediaPlayer();
                FileInputStream fis = getFileInputStream();
                mp.setDataSource(fis.getFD());
                fis.close();
                mp.prepare();
                mp.start();
            } catch (Exception e) {
                Logger.debug("Couldn't play audio");
            }
        }
        private FileInputStream getFileInputStream() throws IOException {
            File resourceFile = new File("/data/data/com.example/files/test.wav");
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(resourceFile));
            bos.write(extractWAVContents());
            bos.flush();
            bos.close();
            return new FileInputStream(resourceFile);
        }
        private byte[] extractWAVContents() {
            // extract wav from zip
        }
    }
    

    将其分配给WebView

    webView.getSettings().setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new PlayAudioWebInterface(), "Audio");