mirror of
				https://gitlab.com/ytdl-org/youtube-dl.git
				synced 2025-11-04 03:37:08 -05:00 
			
		
		
		
	[generic] Add support for camtasia videos (Fixes #3574)
This commit is contained in:
		@@ -15,6 +15,7 @@ from ..utils import (
 | 
			
		||||
    compat_xml_parse_error,
 | 
			
		||||
 | 
			
		||||
    ExtractorError,
 | 
			
		||||
    float_or_none,
 | 
			
		||||
    HEADRequest,
 | 
			
		||||
    orderedSet,
 | 
			
		||||
    parse_xml,
 | 
			
		||||
@@ -305,6 +306,30 @@ class GenericIE(InfoExtractor):
 | 
			
		||||
            'params': {
 | 
			
		||||
                'skip_download': True,
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        # Camtasia studio
 | 
			
		||||
        {
 | 
			
		||||
            'url': 'http://www.ll.mit.edu/workshops/education/videocourses/antennas/lecture1/video/',
 | 
			
		||||
            'playlist': [{
 | 
			
		||||
                'md5': '0c5e352edabf715d762b0ad4e6d9ee67',
 | 
			
		||||
                'info_dict': {
 | 
			
		||||
                    'id': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final',
 | 
			
		||||
                    'title': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final - video1',
 | 
			
		||||
                    'ext': 'flv',
 | 
			
		||||
                    'duration': 2235.90,
 | 
			
		||||
                }
 | 
			
		||||
            }, {
 | 
			
		||||
                'md5': '10e4bb3aaca9fd630e273ff92d9f3c63',
 | 
			
		||||
                'info_dict': {
 | 
			
		||||
                    'id': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final_PIP',
 | 
			
		||||
                    'title': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final - pip',
 | 
			
		||||
                    'ext': 'flv',
 | 
			
		||||
                    'duration': 2235.93,
 | 
			
		||||
                }
 | 
			
		||||
            }],
 | 
			
		||||
            'info_dict': {
 | 
			
		||||
                'title': 'Fenn-AA_PA_Radar_Course_Lecture_1c_Final',
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@@ -389,6 +414,43 @@ class GenericIE(InfoExtractor):
 | 
			
		||||
            'entries': entries,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def _extract_camtasia(self, url, video_id, webpage):
 | 
			
		||||
        """ Returns None if no camtasia video can be found. """
 | 
			
		||||
 | 
			
		||||
        camtasia_cfg = self._search_regex(
 | 
			
		||||
            r'fo\.addVariable\(\s*"csConfigFile",\s*"([^"]+)"\s*\);',
 | 
			
		||||
            webpage, 'camtasia configuration file', default=None)
 | 
			
		||||
        if camtasia_cfg is None:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
        title = self._html_search_meta('DC.title', webpage, fatal=True)
 | 
			
		||||
 | 
			
		||||
        camtasia_url = compat_urlparse.urljoin(url, camtasia_cfg)
 | 
			
		||||
        camtasia_cfg = self._download_xml(
 | 
			
		||||
            camtasia_url, video_id,
 | 
			
		||||
            note='Downloading camtasia configuration',
 | 
			
		||||
            errnote='Failed to download camtasia configuration')
 | 
			
		||||
        fileset_node = camtasia_cfg.find('./playlist/array/fileset')
 | 
			
		||||
 | 
			
		||||
        entries = []
 | 
			
		||||
        for n in fileset_node.getchildren():
 | 
			
		||||
            url_n = n.find('./uri')
 | 
			
		||||
            if url_n is None:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            entries.append({
 | 
			
		||||
                'id': os.path.splitext(url_n.text.rpartition('/')[2])[0],
 | 
			
		||||
                'title': '%s - %s' % (title, n.tag),
 | 
			
		||||
                'url': compat_urlparse.urljoin(url, url_n.text),
 | 
			
		||||
                'duration': float_or_none(n.find('./duration').text),
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            '_type': 'playlist',
 | 
			
		||||
            'entries': entries,
 | 
			
		||||
            'title': title,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def _real_extract(self, url):
 | 
			
		||||
        if url.startswith('//'):
 | 
			
		||||
            return {
 | 
			
		||||
@@ -477,6 +539,11 @@ class GenericIE(InfoExtractor):
 | 
			
		||||
        except compat_xml_parse_error:
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        # Is it a Camtasia project?
 | 
			
		||||
        camtasia_res = self._extract_camtasia(url, video_id, webpage)
 | 
			
		||||
        if camtasia_res is not None:
 | 
			
		||||
            return camtasia_res
 | 
			
		||||
 | 
			
		||||
        # Sometimes embedded video player is hidden behind percent encoding
 | 
			
		||||
        # (e.g. https://github.com/rg3/youtube-dl/issues/2448)
 | 
			
		||||
        # Unescaping the whole page allows to handle those cases in a generic way
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user