prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  BBC iPlayer plugin cannot find VPID
  ### Checklist
  
  - [x] This is a bug report.
  - [ ] This is a feature request.
  - [ ] This is a plugin (improvement) request.
  - [ ] I have read the contribution guidelines.
  
  ### Description
  
  The BBC IPlayer plugin cannot find the VPID for valid urls.
  
  ### Reproduction steps / Explicit stream URLs to test
  
  The following command:
  
  `streamlink -l debug 'http://www.bbc.co.uk/iplayer/episode/b013pnv4/horizon-20112012-2-seeing-stars' best`
  
  produces this output:
  
  ```
  [cli][info] Found matching plugin bbciplayer for URL http://www.bbc.co.uk/iplayer/episode/b013pnv4/horizon-20112012-2-seeing-stars
  [plugin.bbciplayer][debug] Loading streams for episode: b013pnv4
  [plugin.bbciplayer][debug] Looking for vpid on http://www.bbc.co.uk/iplayer/episode/b013pnv4/horizon-20112012-2-seeing-stars
  [plugin.bbciplayer][error] Could not find VPID for episode b013pnv4
  error: No playable streams found on this URL: http://www.bbc.co.uk/iplayer/episode/b013pnv4/horizon-20112012-2-seeing-stars
  
  ```
  
  and the same goes for any other valid iplayer url.
  
  ### Environment details
  
  Operating system: arch linux
  Streamlink and Python versions: streamlink-0.6.0 and python-3.6.1
  
  ### Comments, logs, screenshots, etc.
  
  AFAICS, the page downloaded from the iplayer url does not contain the string "vpid".
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/streamlink/plugins/bbciplayer.py`
  Content:
  ```
  1 from __future__ import print_function
  2 
  3 import base64
  4 import re
  5 from functools import partial
  6 from hashlib import sha1
  7 
  8 from streamlink.plugin import Plugin
  9 from streamlink.plugin.api import http
  10 from streamlink.plugin.api import validate
  11 from streamlink.stream import HDSStream
  12 from streamlink.stream import HLSStream
  13 from streamlink.utils import parse_xml, parse_json
  14 
  15 
  16 class BBCiPlayer(Plugin):
  17     url_re = re.compile(r"""https?://(?:www\.)?bbc.co.uk/iplayer/
  18         (
  19             episode/(?P<episode_id>\w+)|
  20             live/(?P<channel_name>\w+)
  21         )
  22     """, re.VERBOSE)
  23     vpid_re = re.compile(r'"vpid"\s*:\s*"(\w+)"')
  24     tvip_re = re.compile(r'event_master_brand=(\w+?)&')
  25     swf_url = "http://emp.bbci.co.uk/emp/SMPf/1.18.3/StandardMediaPlayerChromelessFlash.swf"
  26     hash = base64.b64decode(b"N2RmZjc2NzFkMGM2OTdmZWRiMWQ5MDVkOWExMjE3MTk5MzhiOTJiZg==")
  27     api_url = ("http://open.live.bbc.co.uk/mediaselector/5/select/"
  28                "version/2.0/mediaset/{platform}/vpid/{vpid}/atk/{vpid_hash}/asn/1/")
  29     platforms = ("pc", "iptv-all")
  30 
  31     mediaselector_schema = validate.Schema(
  32         validate.transform(partial(parse_xml, ignore_ns=True)),
  33         validate.union({
  34             "hds": validate.xml_findall(".//media[@kind='video']//connection[@transferFormat='hds']"),
  35             "hls": validate.xml_findall(".//media[@kind='video']//connection[@transferFormat='hls']")
  36         }),
  37         {validate.text: validate.all(
  38             [validate.all(validate.getattr("attrib"), validate.get("href"))],
  39             validate.transform(lambda x: list(set(x)))  # unique
  40         )}
  41     )
  42 
  43     @classmethod
  44     def can_handle_url(cls, url):
  45         return cls.url_re.match(url) is not None
  46 
  47     @classmethod
  48     def _hash_vpid(cls, vpid):
  49         return sha1(cls.hash + str(vpid).encode("utf8")).hexdigest()
  50 
  51     def find_vpid(self, url):
  52         self.logger.debug("Looking for vpid on {0}", url)
  53         res = http.get(url)
  54         m = self.vpid_re.search(res.text)
  55         return m and m.group(1)
  56 
  57     def find_tvip(self, url):
  58         self.logger.debug("Looking for tvip on {0}", url)
  59         res = http.get(url)
  60         m = self.tvip_re.search(res.text)
  61         return m and m.group(1)
  62 
  63     def mediaselector(self, vpid):
  64         for platform in self.platforms:
  65             url = self.api_url.format(vpid=vpid, vpid_hash=self._hash_vpid(vpid), platform=platform)
  66             stream_urls = http.get(url, schema=self.mediaselector_schema)
  67             for surl in stream_urls.get("hls"):
  68                 for s in HLSStream.parse_variant_playlist(self.session, surl).items():
  69                     yield s
  70             for surl in stream_urls.get("hds"):
  71                 for s in HDSStream.parse_manifest(self.session, surl).items():
  72                     yield s
  73 
  74     def _get_streams(self):
  75         m = self.url_re.match(self.url)
  76         episode_id = m.group("episode_id")
  77         channel_name = m.group("channel_name")
  78 
  79         if episode_id:
  80             self.logger.debug("Loading streams for episode: {0}", episode_id)
  81             vpid = self.find_vpid(self.url)
  82             if vpid:
  83                 self.logger.debug("Found VPID: {0}", vpid)
  84                 for s in self.mediaselector(vpid):
  85                     yield s
  86             else:
  87                 self.logger.error("Could not find VPID for episode {0}", episode_id)
  88         elif channel_name:
  89             self.logger.debug("Loading stream for live channel: {0}", channel_name)
  90             tvip = self.find_tvip(self.url)
  91             if tvip:
  92                 self.logger.debug("Found TVIP: {0}", tvip)
  93                 for s in self.mediaselector(tvip):
  94                     yield s
  95 
  96 
  97 __plugin__ = BBCiPlayer
  98
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/streamlink/plugins/bbciplayer.py b/src/streamlink/plugins/bbciplayer.py
  --- a/src/streamlink/plugins/bbciplayer.py
  +++ b/src/streamlink/plugins/bbciplayer.py
  @@ -20,7 +20,7 @@
               live/(?P<channel_name>\w+)
           )
       """, re.VERBOSE)
  -    vpid_re = re.compile(r'"vpid"\s*:\s*"(\w+)"')
  +    vpid_re = re.compile(r'"ident_id"\s*:\s*"(\w+)"')
       tvip_re = re.compile(r'event_master_brand=(\w+?)&')
       swf_url = "http://emp.bbci.co.uk/emp/SMPf/1.18.3/StandardMediaPlayerChromelessFlash.swf"
       hash = base64.b64decode(b"N2RmZjc2NzFkMGM2OTdmZWRiMWQ5MDVkOWExMjE3MTk5MzhiOTJiZg==")
  
verification_info: {"golden_diff": "diff --git a/src/streamlink/plugins/bbciplayer.py b/src/streamlink/plugins/bbciplayer.py\n--- a/src/streamlink/plugins/bbciplayer.py\n+++ b/src/streamlink/plugins/bbciplayer.py\n@@ -20,7 +20,7 @@\n             live/(?P<channel_name>\\w+)\n         )\n     \"\"\", re.VERBOSE)\n-    vpid_re = re.compile(r'\"vpid\"\\s*:\\s*\"(\\w+)\"')\n+    vpid_re = re.compile(r'\"ident_id\"\\s*:\\s*\"(\\w+)\"')\n     tvip_re = re.compile(r'event_master_brand=(\\w+?)&')\n     swf_url = \"http://emp.bbci.co.uk/emp/SMPf/1.18.3/StandardMediaPlayerChromelessFlash.swf\"\n     hash = base64.b64decode(b\"N2RmZjc2NzFkMGM2OTdmZWRiMWQ5MDVkOWExMjE3MTk5MzhiOTJiZg==\")\n", "issue": "BBC iPlayer plugin cannot find VPID\n### Checklist\r\n\r\n- [x] This is a bug report.\r\n- [ ] This is a feature request.\r\n- [ ] This is a plugin (improvement) request.\r\n- [ ] I have read the contribution guidelines.\r\n\r\n### Description\r\n\r\nThe BBC IPlayer plugin cannot find the VPID for valid urls.\r\n\r\n### Reproduction steps / Explicit stream URLs to test\r\n\r\nThe following command:\r\n\r\n`streamlink -l debug 'http://www.bbc.co.uk/iplayer/episode/b013pnv4/horizon-20112012-2-seeing-stars' best`\r\n\r\nproduces this output:\r\n\r\n```\r\n[cli][info] Found matching plugin bbciplayer for URL http://www.bbc.co.uk/iplayer/episode/b013pnv4/horizon-20112012-2-seeing-stars\r\n[plugin.bbciplayer][debug] Loading streams for episode: b013pnv4\r\n[plugin.bbciplayer][debug] Looking for vpid on http://www.bbc.co.uk/iplayer/episode/b013pnv4/horizon-20112012-2-seeing-stars\r\n[plugin.bbciplayer][error] Could not find VPID for episode b013pnv4\r\nerror: No playable streams found on this URL: http://www.bbc.co.uk/iplayer/episode/b013pnv4/horizon-20112012-2-seeing-stars\r\n\r\n```\r\n\r\nand the same goes for any other valid iplayer url.\r\n\r\n### Environment details\r\n\r\nOperating system: arch linux\r\nStreamlink and Python versions: streamlink-0.6.0 and python-3.6.1\r\n\r\n### Comments, logs, screenshots, etc.\r\n\r\nAFAICS, the page downloaded from the iplayer url does not contain the string \"vpid\".\r\n\n", "before_files": [{"content": "from __future__ import print_function\n\nimport base64\nimport re\nfrom functools import partial\nfrom hashlib import sha1\n\nfrom streamlink.plugin import Plugin\nfrom streamlink.plugin.api import http\nfrom streamlink.plugin.api import validate\nfrom streamlink.stream import HDSStream\nfrom streamlink.stream import HLSStream\nfrom streamlink.utils import parse_xml, parse_json\n\n\nclass BBCiPlayer(Plugin):\n    url_re = re.compile(r\"\"\"https?://(?:www\\.)?bbc.co.uk/iplayer/\n        (\n            episode/(?P<episode_id>\\w+)|\n            live/(?P<channel_name>\\w+)\n        )\n    \"\"\", re.VERBOSE)\n    vpid_re = re.compile(r'\"vpid\"\\s*:\\s*\"(\\w+)\"')\n    tvip_re = re.compile(r'event_master_brand=(\\w+?)&')\n    swf_url = \"http://emp.bbci.co.uk/emp/SMPf/1.18.3/StandardMediaPlayerChromelessFlash.swf\"\n    hash = base64.b64decode(b\"N2RmZjc2NzFkMGM2OTdmZWRiMWQ5MDVkOWExMjE3MTk5MzhiOTJiZg==\")\n    api_url = (\"http://open.live.bbc.co.uk/mediaselector/5/select/\"\n               \"version/2.0/mediaset/{platform}/vpid/{vpid}/atk/{vpid_hash}/asn/1/\")\n    platforms = (\"pc\", \"iptv-all\")\n\n    mediaselector_schema = validate.Schema(\n        validate.transform(partial(parse_xml, ignore_ns=True)),\n        validate.union({\n            \"hds\": validate.xml_findall(\".//media[@kind='video']//connection[@transferFormat='hds']\"),\n            \"hls\": validate.xml_findall(\".//media[@kind='video']//connection[@transferFormat='hls']\")\n        }),\n        {validate.text: validate.all(\n            [validate.all(validate.getattr(\"attrib\"), validate.get(\"href\"))],\n            validate.transform(lambda x: list(set(x)))  # unique\n        )}\n    )\n\n    @classmethod\n    def can_handle_url(cls, url):\n        return cls.url_re.match(url) is not None\n\n    @classmethod\n    def _hash_vpid(cls, vpid):\n        return sha1(cls.hash + str(vpid).encode(\"utf8\")).hexdigest()\n\n    def find_vpid(self, url):\n        self.logger.debug(\"Looking for vpid on {0}\", url)\n        res = http.get(url)\n        m = self.vpid_re.search(res.text)\n        return m and m.group(1)\n\n    def find_tvip(self, url):\n        self.logger.debug(\"Looking for tvip on {0}\", url)\n        res = http.get(url)\n        m = self.tvip_re.search(res.text)\n        return m and m.group(1)\n\n    def mediaselector(self, vpid):\n        for platform in self.platforms:\n            url = self.api_url.format(vpid=vpid, vpid_hash=self._hash_vpid(vpid), platform=platform)\n            stream_urls = http.get(url, schema=self.mediaselector_schema)\n            for surl in stream_urls.get(\"hls\"):\n                for s in HLSStream.parse_variant_playlist(self.session, surl).items():\n                    yield s\n            for surl in stream_urls.get(\"hds\"):\n                for s in HDSStream.parse_manifest(self.session, surl).items():\n                    yield s\n\n    def _get_streams(self):\n        m = self.url_re.match(self.url)\n        episode_id = m.group(\"episode_id\")\n        channel_name = m.group(\"channel_name\")\n\n        if episode_id:\n            self.logger.debug(\"Loading streams for episode: {0}\", episode_id)\n            vpid = self.find_vpid(self.url)\n            if vpid:\n                self.logger.debug(\"Found VPID: {0}\", vpid)\n                for s in self.mediaselector(vpid):\n                    yield s\n            else:\n                self.logger.error(\"Could not find VPID for episode {0}\", episode_id)\n        elif channel_name:\n            self.logger.debug(\"Loading stream for live channel: {0}\", channel_name)\n            tvip = self.find_tvip(self.url)\n            if tvip:\n                self.logger.debug(\"Found TVIP: {0}\", tvip)\n                for s in self.mediaselector(tvip):\n                    yield s\n\n\n__plugin__ = BBCiPlayer\n", "path": "src/streamlink/plugins/bbciplayer.py"}], "after_files": [{"content": "from __future__ import print_function\n\nimport base64\nimport re\nfrom functools import partial\nfrom hashlib import sha1\n\nfrom streamlink.plugin import Plugin\nfrom streamlink.plugin.api import http\nfrom streamlink.plugin.api import validate\nfrom streamlink.stream import HDSStream\nfrom streamlink.stream import HLSStream\nfrom streamlink.utils import parse_xml, parse_json\n\n\nclass BBCiPlayer(Plugin):\n    url_re = re.compile(r\"\"\"https?://(?:www\\.)?bbc.co.uk/iplayer/\n        (\n            episode/(?P<episode_id>\\w+)|\n            live/(?P<channel_name>\\w+)\n        )\n    \"\"\", re.VERBOSE)\n    vpid_re = re.compile(r'\"ident_id\"\\s*:\\s*\"(\\w+)\"')\n    tvip_re = re.compile(r'event_master_brand=(\\w+?)&')\n    swf_url = \"http://emp.bbci.co.uk/emp/SMPf/1.18.3/StandardMediaPlayerChromelessFlash.swf\"\n    hash = base64.b64decode(b\"N2RmZjc2NzFkMGM2OTdmZWRiMWQ5MDVkOWExMjE3MTk5MzhiOTJiZg==\")\n    api_url = (\"http://open.live.bbc.co.uk/mediaselector/5/select/\"\n               \"version/2.0/mediaset/{platform}/vpid/{vpid}/atk/{vpid_hash}/asn/1/\")\n    platforms = (\"pc\", \"iptv-all\")\n\n    mediaselector_schema = validate.Schema(\n        validate.transform(partial(parse_xml, ignore_ns=True)),\n        validate.union({\n            \"hds\": validate.xml_findall(\".//media[@kind='video']//connection[@transferFormat='hds']\"),\n            \"hls\": validate.xml_findall(\".//media[@kind='video']//connection[@transferFormat='hls']\")\n        }),\n        {validate.text: validate.all(\n            [validate.all(validate.getattr(\"attrib\"), validate.get(\"href\"))],\n            validate.transform(lambda x: list(set(x)))  # unique\n        )}\n    )\n\n    @classmethod\n    def can_handle_url(cls, url):\n        return cls.url_re.match(url) is not None\n\n    @classmethod\n    def _hash_vpid(cls, vpid):\n        return sha1(cls.hash + str(vpid).encode(\"utf8\")).hexdigest()\n\n    def find_vpid(self, url):\n        self.logger.debug(\"Looking for vpid on {0}\", url)\n        res = http.get(url)\n        m = self.vpid_re.search(res.text)\n        return m and m.group(1)\n\n    def find_tvip(self, url):\n        self.logger.debug(\"Looking for tvip on {0}\", url)\n        res = http.get(url)\n        m = self.tvip_re.search(res.text)\n        return m and m.group(1)\n\n    def mediaselector(self, vpid):\n        for platform in self.platforms:\n            url = self.api_url.format(vpid=vpid, vpid_hash=self._hash_vpid(vpid), platform=platform)\n            stream_urls = http.get(url, schema=self.mediaselector_schema)\n            for surl in stream_urls.get(\"hls\"):\n                for s in HLSStream.parse_variant_playlist(self.session, surl).items():\n                    yield s\n            for surl in stream_urls.get(\"hds\"):\n                for s in HDSStream.parse_manifest(self.session, surl).items():\n                    yield s\n\n    def _get_streams(self):\n        m = self.url_re.match(self.url)\n        episode_id = m.group(\"episode_id\")\n        channel_name = m.group(\"channel_name\")\n\n        if episode_id:\n            self.logger.debug(\"Loading streams for episode: {0}\", episode_id)\n            vpid = self.find_vpid(self.url)\n            if vpid:\n                self.logger.debug(\"Found VPID: {0}\", vpid)\n                for s in self.mediaselector(vpid):\n                    yield s\n            else:\n                self.logger.error(\"Could not find VPID for episode {0}\", episode_id)\n        elif channel_name:\n            self.logger.debug(\"Loading stream for live channel: {0}\", channel_name)\n            tvip = self.find_tvip(self.url)\n            if tvip:\n                self.logger.debug(\"Found TVIP: {0}\", tvip)\n                for s in self.mediaselector(tvip):\n                    yield s\n\n\n__plugin__ = BBCiPlayer\n", "path": "src/streamlink/plugins/bbciplayer.py"}]}