【问题标题】:How to get direct link of remote video from embedded url within a url in Android using JSoup?如何使用 JSoup 从 Android 中的 url 中的嵌入式 url 获取远程视频的直接链接?
【发布时间】:2017-04-13 00:26:11
【问题描述】:

我之前曾问过有关如何检索视频文件的嵌入式 url 的问题,并且已经成功完成了。现在我有一个不同的问题。 WUnderground API 网络摄像头响应的 json 响应提供了以下 url:

https://www.wunderground.com/webcams/cadot1/902/show.html

使用 JSoup 并根据我最初问题的答案,我能够获得这个嵌入式链接:

https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4

在尝试将视频从该网址“流式传输”到 VideoView 时,我不断收到错误消息“无法播放视频”。查看该链接的源代码后,我注意到需要播放的视频文件没有在 html 中引用,而是在 javascript 中引用。如何获取需要播放的视频文件的直接链接?使用JSoup还是其他进程?

网址https://www.wunderground.com/webcams/cadot1/902/video.html?month=11&year=2016&filename=current.mp4 的来源在<script> 括号内显示了所需视频文件的以下内容:

网址:“//icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1480377508”

我正在使用 JSoup 从响应 url 中获取视频的嵌入 url,如下所示:

    private class VideoLink extends AsyncTask<Void, Void, Void> {
    String title;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog.setTitle("JSOUP Test");
        mProgressDialog.setMessage("Loading...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {
        try {

            // for avoiding javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name
            System.setProperty("jsse.enableSNIExtension", "false");

            // WARNING: do it only if security isn't important, otherwise you have
            // to follow this advices: http://stackoverflow.com/a/7745706/1363265
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){
                public X509Certificate[] getAcceptedIssuers(){return null;}
                public void checkClientTrusted(X509Certificate[] certs, String authType){}
                public void checkServerTrusted(X509Certificate[] certs, String authType){}
            }};

            // Install the all-trusting trust manager
            try {
                SSLContext sc = SSLContext.getInstance("TLS");
                sc.init(null, trustAllCerts, new SecureRandom());
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
                ;
            }

            // Connect to the web site
            Document doc = Jsoup.connect(TEST_URL).get();
            Elements elements = doc.getElementsByClass("videoText");
            // Get the html document title
            for (Element link : elements) {
                String linkHref = link.attr("href");
                // linkHref contains something like video.html?month=11&year=2016&filename=current.mp4
                // TODO check if linkHref ends with current.mp4
                title = linkHref;
            }
        } catch (IOException e) {
            e.printStackTrace();
            mProgressDialog.dismiss();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // Set title into TextView
        resultTxt.setText(title);
        String resVid = TEST_URL;
        Log.d(TAG, "URL: " + resVid);
        Uri resUri = Uri.parse(resVid);
        try {
            // Start the MediaController
            MediaController mediacontroller = new MediaController(
                    MainActivity.this);
            mediacontroller.setAnchorView(resultVidVw);
            // Get the URL from String VideoURL
            Uri video = Uri.parse(resVid);
            resultVidVw.setMediaController(mediacontroller);
            resultVidVw.setVideoURI(video);

        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }

        resultVidVw.requestFocus();
        resultVidVw.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            // Close the progress bar and play the video
            public void onPrepared(MediaPlayer mp) {
                mProgressDialog.dismiss();
                resultVidVw.start();
            }
        });
    }
}

请注意,我需要对响应数组中的每个 JSONObject 执行此操作。

【问题讨论】:

    标签: java android jsoup wunderground


    【解决方案1】:

    这是获取文件的方法:

    注意:提取部分仅适用于网站的当前 html,如果更改,可能无法正常工作!)

    String url = "https://www.wunderground.com/webcams/cadot1/902/video.html";
    int timeout = 100 * 1000;
    
    // Extract video URL
    Document doc = Jsoup.connect(url).timeout(timeout).get();
    Element script = doc.getElementById("inner-content")
            .getElementsByTag("script").last();
    String content = script.data();
    int indexOfUrl = content.indexOf("url");
    int indexOfComma = content.indexOf(',', indexOfUrl);
    String videoUrl = "https:" + content.substring(indexOfUrl + 6, indexOfComma - 1);
    System.out.println(videoUrl);
    

    [输出:https://icons.wunderground.com/webcamcurrent/c/a/cadot1/902/current.mp4?e=1481246112]

    现在您可以通过指定.ignoreContentType(true) 来获取文件,以避免org.jsoup.UnsupportedMimeTypeException.maxBodySize(0) 取消对文件大小的限制。

    // Get video file
    byte[] video = Jsoup.connect(videoUrl)
            .ignoreContentType(true).timeout(timeout).maxBodySize(0)
            .execute().bodyAsBytes();
    

    我不知道你是否可以在Android上玩,但我认为你可以使用org.apache.commons.io.FileUtils保存它(我在Java SE中测试过,但没有在Android开发环境中测试过。)

    // Save video file
    org.apache.commons.io.FileUtils.writeByteArrayToFile(new File("test.mp4"), video);
    

    【讨论】:

    猜你喜欢
    • 2014-05-27
    • 2018-01-21
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 2017-08-20
    • 2016-01-12
    • 2017-09-14
    • 1970-01-01
    相关资源
    最近更新 更多