# Buggy code
def _get_automatic_captions(self, video_id, webpage):
    """We need the webpage for getting the captions url, pass it as an
    argument to speed up the process."""
    self.to_screen("%s: Looking for automatic captions" % video_id)
    mobj = re.search(r";ytplayer.config = ({.*?});", webpage)
    err_msg = "Couldn't find automatic captions for %s" % video_id
    if mobj is None:
        self._downloader.report_warning(err_msg)
        return {}
    player_config = json.loads(mobj.group(1))
    try:
        args = player_config["args"]
        caption_url = args["ttsurl"]
        timestamp = args["timestamp"]
        # We get the available subtitles
        list_params = compat_urllib_parse.urlencode(
            {
                "type": "list",
                "tlangs": 1,
                "asrs": 1,
            }
        )
        list_url = caption_url + "&" + list_params
        caption_list = self._download_xml(list_url, video_id)
        original_lang_node = caption_list.find("track")
        if original_lang_node is None:
            self._downloader.report_warning("Video doesn't have automatic captions")
            return {}
        original_lang = original_lang_node.attrib["lang_code"]
        caption_kind = original_lang_node.attrib.get("kind", "")

        sub_lang_list = {}
        for lang_node in caption_list.findall("target"):
            sub_lang = lang_node.attrib["lang_code"]
            sub_formats = []
            for ext in ["sbv", "vtt", "srt"]:
                params = compat_urllib_parse.urlencode(
                    {
                        "lang": original_lang,
                        "tlang": sub_lang,
                        "fmt": ext,
                        "ts": timestamp,
                        "kind": caption_kind,
                    }
                )
                sub_formats.append(
                    {
                        "url": caption_url + "&" + params,
                        "ext": ext,
                    }
                )
            sub_lang_list[sub_lang] = sub_formats
        return sub_lang_list
    # An extractor error can be raise by the download process if there are
    # no automatic captions but there are subtitles
    except (KeyError, ExtractorError):
        self._downloader.report_warning(err_msg)
        return {}


# Traceback (ValueError)
$ PYTHONPATH=`pwd`  ./bin/youtube-dl --verbose --list-formats 'https://www.youtube.com/watch?v=Ms7iBXnlUO8'
[debug] System config: []
[debug] User config: []
[debug] Command-line args: [u'--verbose', u'--list-formats', u'https://www.youtube.com/watch?v=Ms7iBXnlUO8']
[debug] Encodings: locale UTF-8, fs UTF-8, out UTF-8, pref UTF-8
[debug] youtube-dl version 2015.11.10
[debug] Git HEAD: fcd817a
[debug] Python version 2.7.9 - Linux-3.19.0-33-generic-x86_64-with-Ubuntu-15.04-vivid
[debug] exe versions: ffmpeg 2.5.8-0ubuntu0.15.04.1, ffprobe 2.5.8-0ubuntu0.15.04.1, rtmpdump 2.4
[debug] Proxy map: {}
[youtube] Ms7iBXnlUO8: Downloading webpage
Traceback (most recent call last):
File "./bin/youtube-dl", line 6, in <module>
youtube_dl.main()
File "/home/lukas/work/youtube-dl/youtube_dl/__init__.py", line 410, in main
_real_main(argv)
File "/home/lukas/work/youtube-dl/youtube_dl/__init__.py", line 400, in _real_main
retcode = ydl.download(all_urls)
File "/home/lukas/work/youtube-dl/youtube_dl/YoutubeDL.py", line 1666, in download
url, force_generic_extractor=self.params.get('force_generic_extractor', False))
File "/home/lukas/work/youtube-dl/youtube_dl/YoutubeDL.py", line 661, in extract_info
ie_result = ie.extract(url)
File "/home/lukas/work/youtube-dl/youtube_dl/extractor/common.py", line 290, in extract
return self._real_extract(url)
File "/home/lukas/work/youtube-dl/youtube_dl/extractor/youtube.py", line 1080, in _real_extract
ytplayer_config = json.loads(json_code)
File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Unterminated string starting at: line 1 column 6498 (char 6497)

# Fixed code
def _get_automatic_captions(self, video_id, webpage):
    """We need the webpage for getting the captions url, pass it as an
    argument to speed up the process."""
    self.to_screen("%s: Looking for automatic captions" % video_id)
    player_config = self._get_ytplayer_config(webpage)
    err_msg = "Couldn't find automatic captions for %s" % video_id
    if player_config is None:
        self._downloader.report_warning(err_msg)
        return {}
    try:
        args = player_config["args"]
        caption_url = args["ttsurl"]
        timestamp = args["timestamp"]
        # We get the available subtitles
        list_params = compat_urllib_parse.urlencode(
            {
                "type": "list",
                "tlangs": 1,
                "asrs": 1,
            }
        )
        list_url = caption_url + "&" + list_params
        caption_list = self._download_xml(list_url, video_id)
        original_lang_node = caption_list.find("track")
        if original_lang_node is None:
            self._downloader.report_warning("Video doesn't have automatic captions")
            return {}
        original_lang = original_lang_node.attrib["lang_code"]
        caption_kind = original_lang_node.attrib.get("kind", "")

        sub_lang_list = {}
        for lang_node in caption_list.findall("target"):
            sub_lang = lang_node.attrib["lang_code"]
            sub_formats = []
            for ext in ["sbv", "vtt", "srt"]:
                params = compat_urllib_parse.urlencode(
                    {
                        "lang": original_lang,
                        "tlang": sub_lang,
                        "fmt": ext,
                        "ts": timestamp,
                        "kind": caption_kind,
                    }
                )
                sub_formats.append(
                    {
                        "url": caption_url + "&" + params,
                        "ext": ext,
                    }
                )
            sub_lang_list[sub_lang] = sub_formats
        return sub_lang_list
    # An extractor error can be raise by the download process if there are
    # no automatic captions but there are subtitles
    except (KeyError, ExtractorError):
        self._downloader.report_warning(err_msg)
        return {}