0

I am creating an Android application for downloading facebook videos with the different formats. I used the facebook webview to load the facebook page and followed the method descriped in the link below,

How to detect video in Android WebView with HitTestResult?

as mentioned above used the javascript function to download the video directly.

webView.loadUrl("javascript:(function() { "
                                + "var el = document.querySelectorAll('div[data-sigil]');"
                                + "for(var i=0;i<el.length; i++)"
                                + "{"
                                + "var sigil = el[i].dataset.sigil;"
                                + "if(sigil.indexOf('inlineVideo') > -1){"
                                + "delete el[i].dataset.sigil;"
                                + "var jsonData = JSON.parse(el[i].dataset.store);"
                                + "el[i].setAttribute('onClick', 'FBDownloader.processVideo(\"'+jsonData['src']+'\");');"
                                + "}" + "}" + "})()");

Interface processVideo

@JavascriptInterface
public void processVideo(final String vidData, final String vidID)
{
    try
    {
        String mBaseFolderPath = android.os.Environment
            .getExternalStorageDirectory()
            + File.separator
            + "FacebookVideos" + File.separator;
        if (!new File(mBaseFolderPath).exists())
        {
            new File(mBaseFolderPath).mkdir();
        }
        String mFilePath = "file://" + mBaseFolderPath + "/" + vidID + ".mp4";

        Uri downloadUri = Uri.parse(vidData);
        DownloadManager.Request req = new DownloadManager.Request(downloadUri);
        req.setDestinationUri(Uri.parse(mFilePath));
        req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        DownloadManager dm = (DownloadManager) getSystemService(getApplicationContext().DOWNLOAD_SERVICE);
        dm.enqueue(req);
        Toast.makeText(this, "Download Started", Toast.LENGTH_LONG).show();
    }
    catch (Exception e)
    {
        Toast.makeText(this, "Download Failed: " + e.toString(), Toast.LENGTH_LONG).show();
    }
}

It is working fine. Now I need is to download that video by giving options to download with different formats(360p/720p). Can I successfully do that using the above method or is there any other way to do that?

Can any one suggest any way to do that.

Thanks in advance!!

1 Answers1

1

You can get direct download URL for different resolution (if available). For this you have to parse the data-store attribute which is a json and one of its attribute named 'dashManifest' which contains a XML as string. just parse this XML and all the resolutions video URL present in the XML in a tag named BaseUrl

NB: Facebook streams video and audio separately you can get the type of the media by 'type' tag present int the parsed XML.Comment if you need to know anything specific

below i attached a sample parsed xml from facebook

<?xml version="1.0"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500S" type="static"
     mediaPresentationDuration="PT0H12M21.578S" maxSegmentDuration="PT0H0M2.033S"
     profiles="urn:mpeg:dash:profile:isoff-on-demand:2011,http://dashif.org/guidelines/dash264"
     FBTagsetUsed="waslive_oil">
    <Period duration="PT0H12M21.578S">
        <AdaptationSet segmentAlignment="true" maxWidth="1280" maxHeight="720" maxFrameRate="16000/533" par="16:9"
                       lang="und" subsegmentAlignment="true" subsegmentStartsWithSAP="1">
            <Representation id="880896686086627v" mimeType="video/mp4" codecs="avc1.64001E" width="640" height="360"
                            frameRate="16000/528" sar="1:1" startWithSAP="1" bandwidth="288708"
                            FBEncodingTag="dash_live_md_oil_frag_2_video" FBDefaultQuality="1" FBQualityClass="sd"
                            FBQualityLabel="360p">
                <BaseURL>
                    https://video.fdac31-1.fna.fbcdn.net/v/t58.24163-29/10000000_179254480691335_3242136310202854043_n.mp4?_nc_cat=1&ccb=1-3&_nc_sid=5aebc0&efg=eyJ2ZW5jb2RlX3RhZyI6ImRhc2hfbGl2ZV9tZF9vaWxfZnJhZ18yX3ZpZGVvIn0\u00253D&_nc_eui2=AeH4byTCXnuom722rB1t739m4RczjfwaJOnhFzON_Bok6WesjemJvf6AAXS-mIT2BaBeZdnTgbpxuLfqIROCxPXb&_nc_ohc=pq27eyexXE0AX9Y8aBL&_nc_ht=video.fdac31-1.fna&oh=b6cd1a7f9558b6552a0fd731f26b0c41&oe=607865F2
                </BaseURL>
                <SegmentBase indexRangeExact="true" indexRange="928-5411" FBFirstSegmentRange="5412-88286">
                    <Initialization range="0-927"/>
                </SegmentBase>
            </Representation>
            <Representation id="1101470673682649v" mimeType="video/mp4" codecs="avc1.64000C" width="256" height="144"
                            frameRate="16000/528" sar="1:1" startWithSAP="1" bandwidth="76590"
                            FBEncodingTag="dash_live_qd_oil_frag_2_video" FBQualityClass="sd" FBQualityLabel="144p">
                <BaseURL>
                    https://video.fdac31-1.fna.fbcdn.net/v/t58.24163-29/76771638_778389546126581_1271211815320306451_n.mp4?_nc_cat=1&ccb=1-3&_nc_sid=5aebc0&efg=eyJ2ZW5jb2RlX3RhZyI6ImRhc2hfbGl2ZV9xZF9vaWxfZnJhZ18yX3ZpZGVvIn0\u00253D&_nc_eui2=AeFCKcOeKvIqKh_OTPp7yNRKsRqS5DYzKsyxGpLkNjMqzImp7Xnr27oPkGGzdSSAXuxSauuJYU0rOJxq-2_JFfoX&_nc_ohc=Bjvx6YMJGvEAX-ti9W2&tn=BOH45pToIKt2Dbpq&_nc_ht=video.fdac31-1.fna&oh=a92701eb9f939d734db1c7c034665313&oe=6078235E
                </BaseURL>
                <SegmentBase indexRangeExact="true" indexRange="927-5410" FBFirstSegmentRange="5411-26561">
                    <Initialization range="0-926"/>
                </SegmentBase>
            </Representation>
            <Representation id="469136657731404v" mimeType="video/mp4" codecs="avc1.640015" width="426" height="240"
                            frameRate="16000/528" sar="640:639" startWithSAP="1" bandwidth="154843"
                            FBEncodingTag="dash_live_ld_oil_frag_2_video" FBQualityClass="sd" FBQualityLabel="240p">
                <BaseURL>
                    https://video.fdac31-1.fna.fbcdn.net/v/t58.24163-29/10000000_121549116680806_1261374129181920154_n.mp4?_nc_cat=1&ccb=1-3&_nc_sid=5aebc0&efg=eyJ2ZW5jb2RlX3RhZyI6ImRhc2hfbGl2ZV9sZF9vaWxfZnJhZ18yX3ZpZGVvIn0\u00253D&_nc_eui2=AeGHNRTrop4K87EwJDlkLqGaIJNadRZXbR0gk1p1FldtHWEqbrV7WWYlJ0KTwTD5829mDcWW7xE9QBYvfaFEyV_G&_nc_ohc=lKamnYKfkFUAX-NxcVE&_nc_ht=video.fdac31-1.fna&oh=909496cb650e5a973a1cbfe4c9fa5167&oe=6077EAB6
                </BaseURL>
                <SegmentBase indexRangeExact="true" indexRange="932-5415" FBFirstSegmentRange="5416-46569">
                    <Initialization range="0-931"/>
                </SegmentBase>
            </Representation>
            <Representation id="152826476763600v" mimeType="video/mp4" codecs="avc1.64001F" width="854" height="480"
                            frameRate="16000/528" sar="1280:1281" startWithSAP="1" bandwidth="436215"
                            FBEncodingTag="dash_live_hd_oil_frag_2_video" FBQualityClass="sd" FBQualityLabel="480p">
                <BaseURL>
                    https://video.fdac31-1.fna.fbcdn.net/v/t58.24163-29/10000000_934480347363374_9003012336395628607_n.mp4?_nc_cat=1&ccb=1-3&_nc_sid=5aebc0&efg=eyJ2ZW5jb2RlX3RhZyI6ImRhc2hfbGl2ZV9oZF9vaWxfZnJhZ18yX3ZpZGVvIn0\u00253D&_nc_eui2=AeHWeziPmGVax0rZ5aFWmpeB3F4VGRMQEc7cXhUZExARzuYzBCqh6L_a6cNgKvlavKMhwBDxGzS6e0r7g5Hr-jOW&_nc_ohc=tGdSfqiLRXkAX-tbpqT&_nc_ht=video.fdac31-1.fna&oh=6cf9419a0ca3e002aed595cc708b2eef&oe=60786117
                </BaseURL>
                <SegmentBase indexRangeExact="true" indexRange="932-5415" FBFirstSegmentRange="5416-128976">
                    <Initialization range="0-931"/>
                </SegmentBase>
            </Representation>
            <Representation id="355054559276561v" mimeType="video/mp4" codecs="avc1.640020" width="1280" height="720"
                            frameRate="16000/528" sar="1:1" startWithSAP="1" bandwidth="845834"
                            FBEncodingTag="dash_live_hd1_oil_frag_2_video" FBQualityClass="hd" FBQualityLabel="720p">
                <BaseURL>
                    https://video.fdac31-1.fna.fbcdn.net/v/t58.24163-29/10000000_1074895653020521_3692007604683059549_n.mp4?_nc_cat=1&ccb=1-3&_nc_sid=5aebc0&efg=eyJ2ZW5jb2RlX3RhZyI6ImRhc2hfbGl2ZV9oZDFfb2lsX2ZyYWdfMl92aWRlbyJ9&_nc_eui2=AeE1oD3Xw4kbP72LNiWv_mxAY9khJAs1u1Zj2SEkCzW7Vk3IaKu0VBbRs4ikLF7QQCC99ppzjqASVjeJma8tbUkD&_nc_ohc=JhayX18zZtEAX-SrKzu&_nc_ht=video.fdac31-1.fna&oh=9996495236e41ef0574474e6abf29133&oe=607817A0
                </BaseURL>
                <SegmentBase indexRangeExact="true" indexRange="928-5411" FBFirstSegmentRange="5412-278017">
                    <Initialization range="0-927"/>
                </SegmentBase>
            </Representation>
        </AdaptationSet>
        <AdaptationSet segmentAlignment="true" lang="und" subsegmentAlignment="true" subsegmentStartsWithSAP="1">
            <Representation id="291404125892378a" mimeType="audio/mp4" codecs="mp4a.40.5" audioSamplingRate="48000"
                            startWithSAP="1" bandwidth="65319" FBEncodingTag="dash_live_md_oil_frag_2_audio"
                            FBDefaultQuality="1">
                <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011"
                                           value="2"/>
                <BaseURL>
                    https://video.fdac31-1.fna.fbcdn.net/v/t58.24163-29/100290040_2846605672321798_3199708896663502649_n.mp4?_nc_cat=1&ccb=1-3&_nc_sid=5aebc0&efg=eyJ2ZW5jb2RlX3RhZyI6ImRhc2hfbGl2ZV9tZF9vaWxfZnJhZ18yX2F1ZGlvIn0\u00253D&_nc_eui2=AeGMiyd-n-lk_5kQaA0001uT8KwyO9CI5ljwrDI70IjmWAlRHWBlZjVpOzZCHR5GK1x64VdIOt1x-MccAAgaTec_&_nc_ohc=Xka-_31tgsMAX_y3sKK&_nc_ht=video.fdac31-1.fna&oh=25fd4372f95db40a155ad2a195d31004&oe=6078723D
                </BaseURL>
                <SegmentBase indexRangeExact="true" indexRange="880-5363" FBFirstSegmentRange="5364-21468">
                    <Initialization range="0-879"/>
                </SegmentBase>
            </Representation>
        </AdaptationSet>
    </Period>
</MPD>
  • There is no any attribute in xml called 'dashManifest' – Smeet Jun 04 '21 at 09:49
  • Yeah there is . Iam using this already and its working fine. look carefully l – Ariful Jannat Arif Jun 07 '21 at 16:18
  • 1
    Hi, @ArifulJannatArif. With the help of the hints you gave in your answer, I just managed to get the XML through this script var xml = g.dashManifestmJavaInterface.log(xml); k[j].setAttribute("src", g.src); k[j].onclick = function() { var mainUrl = this.getAttribute("src"); mJavaInterface.dataFromVideoClick(mainUrl,xml); }; } Now I don't understand how to get the different video resolutions out of this XML. Kindly help me in this regard. Thanks. – Nabeel Ahmed Jan 27 '22 at 10:37
  • 1
    this dash manifest is actually a xml document stringified. You can copy a sample dashManifest string to a text editor and write regex expression to parse the different video urls.Otherwise you just copy the dashmanifest string and paste in any xml file in android studio then format it you can see the formatted xml there. Anyways you need to write regular expressions to parse the proper information from there. – Ariful Jannat Arif Jan 29 '22 at 14:45
  • Kindly tell me how I can get the video duration and video size from this data. – Nabeel Ahmed Feb 02 '22 at 10:12
  • Hello @ArifulJannatArif Also, there is one major problem with this implementation. When I download different resolutions videos, those videos don't have sound in it. As I come to know, Facebook provides videos and sounds separate. So kindly tell me how I can download different resolution videos with their sound. – Nabeel Ahmed Feb 10 '22 at 10:12
  • you can't directly download all resolutions video with their audii – Ariful Jannat Arif Feb 10 '22 at 15:54
  • @ArifulJannatArif so it's mean there is no solution for this problem. But I've seen some apps on playstore, which download videos with different resolutions, and those videos have sound. Take a look at this app. https://play.google.com/store/apps/details?id=facebook.video.downloader.savefrom.fb Can you tell me how they are doing this? – Nabeel Ahmed Feb 11 '22 at 10:26