Skip to content

Instantly share code, notes, and snippets.

@bagbag
Last active October 29, 2023 10:20
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bagbag/a2888478d27de0e989cf777f81fb33de to your computer and use it in GitHub Desktop.
Save bagbag/a2888478d27de0e989cf777f81fb33de to your computer and use it in GitHub Desktop.
MediathekViewWeb API Samplecode
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>MediathekViewWeb API</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<script>
const query = {
queries: [
{
fields: ['title', 'topic'],
query: 'sturm der liebe'
},
{
fields: ['channel'],
query: 'ard'
}
],
sortBy: 'timestamp',
sortOrder: 'desc',
future: false,
offset: 0,
size: 10,
duration_min: 20,
duration_max: 100
};
const queryString = JSON.stringify(query);
const request = new XMLHttpRequest();
const requestURL = 'https://mediathekviewweb.de/api/query';
request.open("POST", requestURL);
request.addEventListener('load', function (event) {
let response;
try {
response = JSON.parse(request.responseText);
} catch (e) { }
if (request.status == 200 && typeof response != 'undefined') {
for (let i = 0; i < response.result.results.length; i++) {
let entry = response.result.results[i];
let row = $('<tr>');
row.append($('<td>').text(entry.channel));
row.append($('<td>').text(entry.topic));
row.append($('<td>').text(entry.title));
row.append($('<td>').text(entry.description));
row.append($('<td>').text(entry.url_video));
$('#mediathek > tbody').append(row);
}
$('#responseText').text(JSON.stringify(response, null, 2));
} else {
if (response) {
console.log(response.err);
$('#errorText').html(response.err.join('</br>'));
}
else {
$('#errorText').html(request.statusText + '</br>' + request.responseText);
}
}
});
request.send(queryString);
</script>
<style>
table,
th,
td {
border: 1px solid black;
border-collapse: collapse;
}
th,
td {
padding: 5px;
}
th {
text-align: left;
}
</style>
<body>
<table id="mediathek" class="table table-striped table-hover">
<thead>
<tr>
<th>Sender</th>
<th>Thema</th>
<th>Titel</th>
<th>Beschreibung</th>
<th>URL</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p id="errorText"></p>
</br>
<p id="responseText" style="white-space:pre-wrap;"></p>
</body>
</html>
@axaneco
Copy link

axaneco commented Aug 22, 2021

For everyone using PHP, this is a working sample code that produces the same result as the index.html above:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>MediathekViewWeb API</title>
    </head>
    <style>
        table, th, td {
            border: 1px solid black;
            border-collapse: collapse;
        }

        th, td {
            padding: 5px;
        }

        th {
            text-align: left;
        }
    </style>
    <body>
        <?php
        $api_url = 'https://mediathekviewweb.de/api/query';

        function callmvapi($api_url, $query) {
            $ch = curl_init($api_url);
            curl_setopt_array($ch, array(
                CURLOPT_POST => 1,
                CURLOPT_POSTFIELDS => $query,
                CURLOPT_HTTPHEADER => array('User-Agent: ax mvclient 0.1.1', 'Content-Type: text/plain'),
                CURLOPT_RETURNTRANSFER => 1
            ));
            $result = curl_exec($ch);
            curl_close($ch);
            return $result;
        }

        $query = '{"queries":[{"fields":["title","topic"],"query":"sturm der liebe"},'
                . '{"fields":["channel"],"query":"ndr"}],"sortBy":"timestamp","sortOrder":"desc",'
                . '"future":"false","offset":"0","size":"10"}';

        $result = callmvapi($api_url, $query);
        $array = json_decode($result, true);
        ?>

        <table id="mediathek" class="table table-striped table-hover">
            <thead>
                <tr>
                    <th>Sender</th>
                    <th>Thema</th>
                    <th>Titel</th>
                    <th>Beschreibung</th>
                    <th>URL</th>
                </tr>
            </thead>
            <tbody>
                <?php
                foreach ($array['result']['results'] as $entry) {
                    echo '<tr>';
                    echo '<td>' . $entry['channel'] . '</td>';
                    echo '<td>' . $entry['topic'] . '</td>';
                    echo '<td>' . $entry['title'] . '</td>';
                    echo '<td>' . $entry['description'] . '</td>';
                    echo '<td>' . $entry['url_video'] . '</td>';
                    echo '</tr>';
                }
                ?>  
            </tbody>
        </table>

        <?php
        echo '<pre>';
        echo nl2br(json_encode(json_decode($result), JSON_PRETTY_PRINT));
        echo '</pre>';
        ?>
    </body>
</html>

@MrFly72
Copy link

MrFly72 commented Nov 27, 2021

And this is the same example which makes use of Powershell Desktop (5.1) or Powershell Core (Windows+Linux tested):

$MediathekQuery = @{
    queries = @(
        # fields is casted to array, as some queries require fields to be an array, even if only one value!
        @{fields = @("title","topic"); query = "sturm der liebe" }
        @{fields = @("channel"); query = "ard" }
    )
    sortBy = "timestamp"
    sortOrder = "desc"
    future = $false # $true or $false
    offset = 0
    size = 10
    duration_min = 20 # in seconds
    duration_max = 100 # in seconds
}

if ($PSVersionTable.PSEdition -eq "Desktop") {
    $QueryJSON = $MediathekQuery | ConvertTo-Json -Depth 20
}
else {
    #Powershell Core supports a new escaping, which is needed for umlauts in core, but not in 5.1
    $QueryJSON = $MediathekQuery | ConvertTo-Json -Depth 20 -EscapeHandling EscapeNonAscii
}

$Antwort = Invoke-RestMethod -Method Post -Uri "https://mediathekviewweb.de/api/query" -Body $QueryJSON -ContentType "text/plain"

Output is a Powershell Object in the following form:

channel            : ARD
topic              : Sturm der Liebe
title              : Hinter den Kulissen: Backstage bei der Textprobe von Erich und Lorenzo
description        : Achtung, volle Konzentration! In diesem Behind-the-Scenes-Clip zeigen wir Euch, wie Erich Altenkopf alias Dr. Michael Niederbühl und 
                     Robert-Saalfeld-Darsteller Lorenzo Patané kurz vor dem Dreh nochmal ihren Text durchgehen.
timestamp          : 1627903500
duration           : 59
size               : 15728640
url_website        : https://www.ardmediathek.de/video/Y3JpZDovL2Rhc2Vyc3RlLmRlL3N0dXJtIGRlciBsaWViZS8zNmI5NjM0Ni04MDliLTRjYTItYTdhOC1iOTc4OTg0Mjg1NDE
url_subtitle       : 
url_video          : https://pdvideosdaserste-a.akamaihd.net/int/2021/08/02/36b96346-809b-4ca2-a7a8-b97898428541/960-1_948286.mp4
url_video_low      : https://pdvideosdaserste-a.akamaihd.net/int/2021/08/02/36b96346-809b-4ca2-a7a8-b97898428541/640-1_948286.mp4
url_video_hd       : https://pdvideosdaserste-a.akamaihd.net/int/2021/08/02/36b96346-809b-4ca2-a7a8-b97898428541/1280-1_948286.mp4
filmlisteTimestamp : 1627935420
id                 : hikmS6Vj8lCcV5iVpXxb1DKD32rfnVoNBTx8dxzvhqg=

Easy to parse with eg.:
$Antwort[0].url_video to get the video URL.

@Axel-Erfurt
Copy link

using duration_min and duration_max will result in not all results being displayed.

@MrFly72
Copy link

MrFly72 commented Jan 9, 2023

I tried to check on this, but could not find any problem.
Are you aware, that the value is in seconds?
I mean 20-100 is really a very very small TV-Show ;-)

@Axel-Erfurt
Copy link

You're right. The values ​​in the example are perhaps a bit unfortunate.

@MrFly72
Copy link

MrFly72 commented Jan 9, 2023

I added the information behind my powershell code.

@linusgke
Copy link

I'm currently experimenting with the API.
When trying to query for url_website i get the following error:

{"bool" : {
    "must" : [
      {
        "bool" : {
          "should" : [
            {
              "multi_match" : {
                "query" : "https://www.ardmediathek.de/video/fernsehfilm/brecht-oder-doku-drama-1-2/wdr/Y3JpZDovL3dkci5kZS9CZWl0cmFnLWNlZjM1NGFjLTU0ZTctNGRjZS04ZGUwLTc4MjBjMjFhYjc4Yw",
                "fields" : [
                  "url_website^1.0"
                ],
                "type" : "cross_fields",
                "operator" : "AND",
                "slop" : 0,
                "prefix_length" : 0,
                "max_expansions" : 50,
                "zero_terms_query" : "NONE",
                "auto_generate_synonyms_phrase_query" : true,
                "fuzzy_transpositions" : true,
                "boost" : 1.0
              }
            }
          ],
          "adjust_pure_negative" : true,
          "boost" : 1.0
        }
      }
    ],
    "adjust_pure_negative" : true,
    "boost" : 1.0
  }
}, with { index_uuid="6J8SqRTpS_iHVOl1LAH1uw" & index="filmliste" }

Anybody got any idea what I'm doing wrong? Or is it simply not possible to query by URL?

@Wongraven
Copy link

Hi all you pro-developers! I am experimenting with this API in python and i am seeing some behaviour i dont understand. It seems as if there is a limitation to the amount of information one can recieve from the API. 15 entries seem to be the maximum. Can anyone please help me get more than the 15 entries?

@linusgke
Copy link

Hey there @Wongraven 👋

Using the above mentioned JavaScript/HTML and the following query:

const query = {
    queries: [
      {
        fields: ['title', 'topic'],
        query: 'sturm der liebe'
      },
      {
        fields: ['channel'],
        query: 'ard'
      }
    ],
    sortBy: 'timestamp',
    sortOrder: 'desc',
    future: false,
    offset: 0,
    size: 100, <-- That's what I changed
    duration_min: 20,
    duration_max: 100
  };

I get 100 entries in response. Could you post your code here, so we can take a look at the problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment