Index: action.py
==================================================================
--- action.py
+++ action.py
@@ -104,10 +104,11 @@
    ("asx" , r""" (?i) <asx\b """),
    ("smil", r""" <smil[^>]*> .* <seq> """),
    ("html", r""" (?i)<(audio|video)\b[^>]+\bsrc\s*=\s*["']?https?:// """),
    ("wpl",  r""" <\?wpl \s+ version="1\.0" \s* \?> """),
    ("b4s",  r""" <WinampXML> """),   # http://gonze.com/playlists/playlist-format-survey.html
+   ("qtl",  r""" <?quicktime\d+type="application/x-quicktime-media-link"\d*?> """),
    ("jspf", r""" ^ \s* \{ \s* "playlist": \s* \{ """),
    ("asf",  r""" ^ \[Reference\] .*? ^Ref\d+= """),
    ("url",  r""" ^ \[InternetShortcut\] .*? ^URL= """),
 ("desktop", r""" ^ \[Desktop Entry\] .*? ^Link= """),
    ("json", r""" "url": \s* "\w+:\\?/\\?/ """),
@@ -145,11 +146,13 @@
     except:
         log.ERR("Command not found:", cmd)
 
 # Open help browser, chm, or streamtuner2 pages
 def help(*args):
-    for path in [p for p in ("./help", "/usr/share/doc/streamtuner2/help") if os.path.exists(p)]:
+    for path in ("./help", "/usr/share/doc/streamtuner2/help", "./usr/share/doc/streamtuner2"):
+        if not os.path.exists(path):
+            continue
         if conf.windows:
             return run(("%s/help.chm" % path).replace("/", '\\'))
         else:
             return run("yelp %s" % path)
     return browser("http://fossil.include-once.org/streamtuner2/doc/tip/help/html/index.html")
@@ -534,10 +537,14 @@
         ),
         "asf": dict(
             url   = r" (?m) ^ \s*Ref\d+ = (\w+://[^\s]+) ",
             unesc = "xml",
         ),
+        "qtl": dict(
+            url   = r" <embed\s+src=[\"\']([^\"\']+)[\"\']\s*/>",
+            unesc = "xml",
+        ),
         "url": dict(
             url   = r"(?m) ^URL=(\w+://.+)",
         ),
         "desktop": dict(
             url   = r"(?m) ^URL=(\w+://.+)",
@@ -740,10 +747,16 @@
         for row in rows:
             txt += """\t<entry>\n\t\t<title>%s</title>\n\t\t<ref href="%s"/>\n\t</entry>\n""" % (xmlentities(row["title"]), xmlentities(row["url"]))
         txt += """</asx>\n"""
         return txt
 
+
+    # QTL
+    def qtl(self, rows):
+        return """<?xml version="1.0"?>\n<?quicktime type="application/x-quicktime-media-link"?>\n"""\
+            + "<embed src=\"%s\" />\n" % xmlentities(rows[0]["url"])
+
 
     # SMIL
     def smil(self, rows):
         txt = """<smil>\n<head>\n\t<meta name="title" content="%s"/>\n</head>\n<body>\n\t<seq>\n""" % (rows[0]["title"])
         for row in rows:

Index: st2.py
==================================================================
--- st2.py
+++ st2.py
@@ -340,11 +340,11 @@
         row = self.row()
         default_fn = row["title"] + ".m3u"
         fn = uikit.save_file("Save Stream", None, default_fn, [(".m3u","*m3u"),(".pls","*pls"),(".xspf","*xspf"),(".jspf","*jspf"),(".smil","*smil"),(".asx","*asx"),("all files","*")])
         if fn:
             source = row.get("listformat", self.channel().listformat)
-            dest = (re.findall("\.(m3u|pls|xspf|jspf|json|smil|asx|wpl)8?$", fn) or ["pls"])[0]
+            dest = (re.findall("\.(m3u|pls|xspf|jspf|json|smil|asx|wpl|qtl)8?$", fn) or ["pls"])[0]
             action.save_playlist(source=source, multiply=True).file(rows=[row], fn=fn, dest=dest)
         pass
 
     # Save current stream URL into clipboard
     def menu_copy(self, w):