Get instagram's video media source using oembed endpoints

后端 未结 3 1292
一向
一向 2021-02-03 15:04

THE CONTEXT

I have a piece of (jQuery) ajax code that has been happily working for about 9 months until the last couple of weeks or so.

This code uses Instagr

相关标签:
3条回答
  • 2021-02-03 15:24

    UPDATE [March 2015] : For an extended and updated version of this solution, please visit http://www.picssel.com/build-a-simple-instagram-api-case-study/


    @ProllyGeek's answer provided a good workaround to scrape the Instagram video page (well deserved bounty), however it relies on the whateverorigin.org third-party service, which will work fine unless the service eventually becomes unavailable.

    Since the latest already happened to me in a production environment, I had to look for a more reliable alternative so I decided to use php's file_get_contents to scrape the video link from an own-hosted PHP module.

    I basically followed the same logic proposed by @ProllyGeek but translated to PHP so:

    The getVideoLink.php module :

    <?php
    header('Content-Type: text/html; charset=utf-8');
    function clean_input($data){
        $data = trim($data);
        $data = stripslashes($data);
        $data = strip_tags($data);
        $data = htmlspecialchars($data);
        return $data;
    };
    $instalink = clean_input( $_GET['instalink'] );    
    if (!empty($instalink)) {
        $response = clean_input( @ file_get_contents( $instalink ) );
        $start_position = strpos( $response ,'video_url&quot;:&quot;' ); // the start position
        $start_positionlength = strlen('video_url&quot;:&quot;'); // string length to trim before
        $end_position = strpos($response ,'&quot;,&quot;usertags'); // the end position
        $mp4_link = substr( $response, ( $start_position + $start_positionlength ), ( $end_position - ( $start_position + $start_positionlength ) ) );
        echo $mp4_link;
    };
    ?>
    

    Of course, you may need to analyze the response manually to know what you are looking for.

    Then the AJAX call to the PHP module from my main page :

    var instaLink = "http://instagram.com/p/mOFsFhAp4f/"; // the Coca Cola video link
    jQuery(document).ready(function ($) {
        $.ajax({
            url: "getVideoLink.php?instalink="+instaLink,
            dataType : "html",
            cache : false,
            success : function (data) {
                console.log(data); // returns http://distilleryvesper3-15.ak.instagram.com/b0ce80e6b91111e3a16a122b8b9af17f_101.mp4
            },
            error : function () {
                console.log("error in ajax");
            }
        });
    }); // ready 
    

    It's assumed your host supports php to use this method.


    EDIT [November 19, 2014]

    I have modified the getVideoLink.php module (now getInstaLinkJSON.php) to actually get the JSON information from an specific Instagram media link like http://instagram.com/p/mOFsFhAp4f/

    This is much more useful than just scraping the video's URL and can be used for images too.

    The new getInstaLinkJSON.php code :

    <?php
    function clean_input($data){
        $data = trim($data);
        $data = strip_tags($data);
        return $data;
    };
    // clean user input
    function clean_input_all($data){
        $data = trim($data);
        $data = stripslashes($data);
        $data = strip_tags($data);
        $data = htmlspecialchars($data);
        return $data;
    };
    $instaLink = clean_input_all( $_GET['instaLink'] );
    
    if( !empty($instaLink) ){
        header('Content-Type: application/json; charset=utf-8');
        $response = clean_input( @ file_get_contents($instaLink) );
        $response_length = strlen($response);
        $start_position = strpos( $response ,'window._sharedData = ' ); // the start position
        $start_positionlength = strlen('window._sharedData = '); // string length to trim before
        $trimmed = trim( substr($response, ( $start_position + $start_positionlength ) ) ); // trim extra spaces and carriage returns
        $jsondata = substr( $trimmed, 0, -1); // remove extra ";" added at the end of the javascript variable 
        echo $jsondata;
    } elseif( empty($instaLink) ) {
        die(); //only accepts instaLink as parameter
    }
    ?>
    

    I am sanitizing both the user's input and the file_get_contents() response, however I am not stripping slashes or HTML characters from the last since I will be returning a JSON response.

    Then the AJAX call:

    var instaLink = "http://instagram.com/p/mOFsFhAp4f/"; // demo
    jQuery.ajax({
        url: "getInstaLinkJSON.php?instalink=" + instaLink,
        dataType : "json", // important!!!
        cache : false,
        success : function ( response ) {
            console.log( response ); // returns json
            var media = response.entry_data.DesktopPPage[0].media;
    
            // get the video URL
            // media.is_video : returns true/false
    
            if( media.is_video ){
                console.log( media.video_url ); // returns http://distilleryvesper3-15.ak.instagram.com/b0ce80e6b91111e3a16a122b8b9af17f_101.mp4
            }
        },
        error : function () {
            console.log("error in ajax");
        }
    });
    

    EDIT [May 20, 2020]

    currently working PHP

    <?php
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: *");
    function clean_input($data){
        $data = trim($data);
        $data = strip_tags($data);
        return $data;
    };
    // clean user input
    function clean_input_all($data){
        $data = trim($data);
        $data = stripslashes($data);
        $data = strip_tags($data);
        $data = htmlspecialchars($data);
        return $data;
    };
    $instaLink = clean_input_all( $_GET['instaLink'] );
    
    if( !empty($instaLink) ){
        header('Content-Type: application/json; charset=utf-8');
        $response = clean_input( @ file_get_contents($instaLink) );
        $response_length = strlen($response);
        $start_position = strpos( $response ,'window._sharedData = ' ); // the start position
        $start_positionlength = strlen('window._sharedData = '); // string length to trim before
        $trimmed = trim( substr($response, ( $start_position + $start_positionlength ) ) ); // trim extra spaces and carriage returns
        $jsondata = substr( $trimmed, 0, -1); // remove extra ";" added at the end of the javascript variable 
        $jsondata = explode('window.__initialDataLoaded', $jsondata);
        echo substr(trim($jsondata[0]), 0, -1);
    } elseif( empty($instaLink) ) {
        die(); //only accepts instaLink as parameter
    }
    ?>
    
    0 讨论(0)
  • 2021-02-03 15:32

    This may not be the best or optimum answer , but as i believe this will solve your issue for now , so you may consider it a work around:

    Thanks to whateverorigin.org service we are able to fetch cross origin json , which has all the data you may request , all you have to do is converting the returned object to string , then use regex to fetch whatever data you need.

    var myvideourl="http://instagram.com/p/mOFsFhAp4f/"
    $.ajaxSetup({
        scriptCharset: "utf-8", //maybe "ISO-8859-1"
        contentType: "application/json; charset=utf-8"
    });
    
    $.getJSON('http://whateverorigin.org/get?url=' + 
        encodeURIComponent(myvideourl) + '&callback=?',
        function(data) {
    
            var xx=data.contents
            var dataindex=xx.search('<meta property="og:video" content=')
            var end=xx.indexOf('/>', dataindex);
            var yy=xx.slice(dataindex,end+2)
            var metaobject=$.parseHTML(yy)
            alert(metaobject[0].content)
            console.log(metaobject[0].content)
    });
    

    Here is and example:

    JS Fiddle Demo

    works well for me , but only tried it on the CocaCola video , havent tried it on other links.

    0 讨论(0)
  • 2021-02-03 15:36

    I am not a jQuery expert. Putting aside the syntax error(s), could this be any use?

    var publicUrl = "http://instagram.com/p/dAu7UPgvn0"; //photo
    var publicUrl = "http://instagram.com/p/mOFsFhAp4f"; //video
    
    
    var URL = "http://api.instagram.com/oembed?url="+publicUrl;
    
    $(document).ready(function () {
        $.ajax({
            url: URL,
            publicurl: publicUrl,
            dataType: "jsonp",
            cache: false,
            success: function (response) {
                success: function (response) {
                    var mediaSrc;
                    if (response.type === 'photo') {
                        mediaSrc = response.url;
                    } else {
                        mediaSrc = $(publicurl).find('div.Video vStatesHide Frame').src;
                    }
                    console.log(mediaSrc);
                }
            },
            error: function () {
                console.log("couldn't process the instagram url");
            }
        });
    });
    
    0 讨论(0)
提交回复
热议问题