diff --git a/BBDown/BBDownParser.cs b/BBDown/BBDownParser.cs
index ffc431b99..cc47cbeae 100644
--- a/BBDown/BBDownParser.cs
+++ b/BBDown/BBDownParser.cs
@@ -13,8 +13,21 @@ public static string GetPlayJson(string aid, string cid, string epId, bool tvApi
             string prefix = tvApi ? (bangumi ? "api.snm0516.aisee.tv/pgc/player/api/playurltv" : "api.snm0516.aisee.tv/x/tv/ugc/playurl")
                         : (bangumi ? "api.bilibili.com/pgc/player/web/playurl" : "api.bilibili.com/x/player/playurl");
             string api = $"https://{prefix}?avid={aid}&cid={cid}&qn={qn}&type=&otype=json" + (tvApi ? "" : "&fourk=1") +
-                "&fnver=0&fnval=16" + (tvApi ? "&device=android&platform=android&mobi_app=android_tv_yst&npcybs=0&force_host=0&build=102801" : "") +
+                "&fnver=0&fnval=16" + (tvApi ? "&device=android&platform=android" +
+                "&mobi_app=android_tv_yst&npcybs=0&force_host=0&build=102801" +
+                (Program.TOKEN != "" ? $"&access_key={GetQueryString("access_token", Program.TOKEN)}" : "") : "") +
                 (bangumi ? $"&module=bangumi&ep_id={epId}&fourk=1" + "&session=" : "");
+            if (tvApi && bangumi)
+            {
+                api = (Program.TOKEN != "" ? $"access_key={GetQueryString("access_token", Program.TOKEN)}&" : "") +
+                    $"aid={aid}&appkey=4409e2ce8ffd12b8&build=102801" +
+                    $"&cid={cid}&device=android&ep_id={epId}&expire=0" +
+                    $"&fnval=16&fnver=0&fourk=1" +
+                    $"&mid=0&mobi_app=android_tv_yst" +
+                    $"&module=bangumi&npcybs=0&otype=json&platform=android" +
+                    $"&qn={qn}&ts={GetTimeStamp(true)}";
+                api = $"https://{prefix}?" + api + (bangumi ? $"&sign={GetSign(api)}" : "");
+            }
             //Console.WriteLine(api);
             string webJson = GetWebSource(api);
             //以下情况从网页源代码尝试解析
diff --git a/BBDown/BBDownUtil.cs b/BBDown/BBDownUtil.cs
index 298e8206a..d24b368fd 100644
--- a/BBDown/BBDownUtil.cs
+++ b/BBDown/BBDownUtil.cs
@@ -6,13 +6,16 @@
 using System.Collections.Specialized;
 using System.Diagnostics;
 using System.IO;
+using System.Linq;
 using System.Net;
 using System.Net.Cache;
 using System.Net.Http;
 using System.Net.Http.Headers;
+using System.Security.Cryptography;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
+using System.Web;
 using static BBDown.BBDownEntity;
 
 namespace BBDown
@@ -182,7 +185,8 @@ public static async Task DownloadFile(string url, string path)
             {
                 long totalLength = -1;
                 WebClient client = new WebClient();
-                client.Headers.Add("Referer", "https://www.bilibili.com");
+                if (!url.Contains("platform=android_tv_yst"))
+                    client.Headers.Add("Referer", "https://www.bilibili.com");
                 client.Headers.Add("User-Agent", "Mozilla/5.0");
                 client.Headers.Add("Cookie", Program.COOKIE);
                 client.Credentials = CredentialCache.DefaultCredentials;
@@ -228,7 +232,8 @@ public static void MultiThreadDownloadFile(string url, string path)
                             request.AllowAutoRedirect = true;
                             request.KeepAlive = false;
                             request.Method = "GET";
-                            request.Referer = "https://www.bilibili.com";
+                            if (!url.Contains("platform=android_tv_yst"))
+                                request.Referer = "https://www.bilibili.com";
                             request.UserAgent = "Mozilla/5.0";
                             request.Headers.Add("Cookie", Program.COOKIE);
                             if (clip.to != -1)
@@ -358,7 +363,8 @@ public static string[] GetFiles(string dir, string ext)
         private static long GetFileSize(string url)
         {
             WebClient webClient = new WebClient();
-            webClient.Headers.Add("Referer", "https://www.bilibili.com");
+            if (!url.Contains("platform=android_tv_yst"))
+                webClient.Headers.Add("Referer", "https://www.bilibili.com");
             webClient.Headers.Add("User-Agent", "Mozilla/5.0");
             webClient.OpenRead(url);
             long totalSizeBytes = Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
@@ -441,5 +447,79 @@ public static string GetSession(string buvid3)
             //这个参数可以没有 所以此处就不写具体实现了
             throw new NotImplementedException();
         }
+
+        public static string GetSign(string parms)
+        {
+            string toEncode = parms + "59b43e04ad6965f34319062b478f83dd";
+            MD5 md5 = MD5.Create();
+            byte[] bs = Encoding.UTF8.GetBytes(toEncode);
+            byte[] hs = md5.ComputeHash(bs);
+            StringBuilder sb = new StringBuilder();
+            foreach (byte b in hs)
+            {
+                sb.Append(b.ToString("x2"));
+            }
+            return sb.ToString();
+        }
+
+        public static string GetTimeStamp(bool bflag)
+        {
+            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+            string ret = string.Empty;
+            if (bflag)
+                ret = Convert.ToInt64(ts.TotalSeconds).ToString();
+            else
+                ret = Convert.ToInt64(ts.TotalMilliseconds).ToString();
+
+            return ret;
+        }
+
+        //https://stackoverflow.com/questions/1344221/how-can-i-generate-random-alphanumeric-strings
+        private static Random random = new Random();
+        public static string GetRandomString(int length)
+        {
+            const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789";
+            return new string(Enumerable.Repeat(chars, length)
+              .Select(s => s[random.Next(s.Length)]).ToArray());
+        }
+
+        //https://stackoverflow.com/a/45088333
+        public static string ToQueryString(NameValueCollection nameValueCollection)
+        {
+            NameValueCollection httpValueCollection = HttpUtility.ParseQueryString(String.Empty);
+            httpValueCollection.Add(nameValueCollection);
+            return httpValueCollection.ToString();
+        }
+
+        public static NameValueCollection GetTVLoginParms()
+        {
+            NameValueCollection sb = new NameValueCollection();
+            DateTime now = DateTime.Now;
+            string deviceId = GetRandomString(20);
+            string buvid = GetRandomString(37);
+            string fingerprint = $"{now.ToString("yyyyMMddHHmmssfff")}{GetRandomString(45)}";
+            sb.Add("appkey","4409e2ce8ffd12b8");
+            sb.Add("auth_code", "");
+            sb.Add("bili_local_id", deviceId);
+            sb.Add("build", "102801");
+            sb.Add("buvid", buvid);
+            sb.Add("channel", "master");
+            sb.Add("device", "OnePlus");
+            sb.Add($"device_id", deviceId);
+            sb.Add("device_name", "OnePlus7TPro");
+            sb.Add("device_platform", "Android10OnePlusHD1910");
+            sb.Add($"fingerprint", fingerprint);
+            sb.Add($"guid", buvid);
+            sb.Add($"local_fingerprint", fingerprint);
+            sb.Add($"local_id", buvid);
+            sb.Add("mobi_app", "android_tv_yst");
+            sb.Add("networkstate", "wifi");
+            sb.Add("platform", "android");
+            sb.Add("sys_ver", "29");
+            sb.Add($"ts", GetTimeStamp(true));
+            sb.Add($"sign", GetSign(ToQueryString(sb)));
+
+            return sb;
+        }
     }
 }
diff --git a/BBDown/Program.cs b/BBDown/Program.cs
index de51d376e..aa70124ff 100644
--- a/BBDown/Program.cs
+++ b/BBDown/Program.cs
@@ -16,12 +16,14 @@
 using static BBDown.BBDownParser;
 using static BBDown.BBDownLogger;
 using static BBDown.BBDownMuxer;
+using System.Text;
 
 namespace BBDown
 {
     class Program
     {
         public static string COOKIE = "";
+        public static string TOKEN = "";
         static Dictionary<string, string> qualitys = new Dictionary<string, string>() {
             {"120","超清 4K" }, {"116","高清 1080P60" },{"112","高清 1080P+" },
             {"80","高清 1080P" }, {"74","高清 720P60" },{"64","高清 720P" },
@@ -49,6 +51,7 @@ class MyOption
             public bool MultiThread { get; set; }
             public string SelectPage { get; set; }
             public string Cookie { get; set; }
+            public string AccessToken { get; set; }
         }
 
         public static int Main(params string[] args)
@@ -83,16 +86,24 @@ public static int Main(params string[] args)
                     "选择指定分p或分p范围"),
                 new Option<string>(
                     new string[]{ "--cookie" ,"-c"},
-                    "设置字符串cookie用以下载网页接口的会员内容")
+                    "设置字符串cookie用以下载网页接口的会员内容"),
+                new Option<string>(
+                    new string[]{ "--access-token" ,"-a"},
+                    "设置access_token用以下载TV接口的会员内容")
             };
 
             Command loginCommand = new Command(
                 "login",
-                "通过APP扫描二维码以登录您的账号");
+                "通过APP扫描二维码以登录您的WEB账号");
             rootCommand.AddCommand(loginCommand);
+            Command loginTVCommand = new Command(
+                "logintv",
+                "通过APP扫描二维码以登录您的TV账号");
+            rootCommand.AddCommand(loginTVCommand);
             rootCommand.Description = "BBDown是一个免费且便捷高效的哔哩哔哩下载/解析软件.";
             rootCommand.TreatUnmatchedTokensAsErrors = true;
 
+            //WEB登录
             loginCommand.Handler = CommandHandler.Create(delegate
             {
                 try
@@ -147,6 +158,60 @@ public static int Main(params string[] args)
                 catch (Exception e) { LogError(e.Message); }
             });
 
+            //TV登录
+            loginTVCommand.Handler = CommandHandler.Create(delegate
+            {
+                try
+                {
+                    string loginUrl = "https://passport.snm0516.aisee.tv/x/passport-tv-login/qrcode/auth_code";
+                    string pollUrl = "https://passport.bilibili.com/x/passport-tv-login/qrcode/poll";
+                    var parms = GetTVLoginParms();
+                    Log("获取登录地址...");
+                    WebClient webClient = new WebClient();
+                    byte[] responseArray = webClient.UploadValues(loginUrl, parms);
+                    string web = Encoding.UTF8.GetString(responseArray);
+                    string url = JObject.Parse(web)["data"]["url"].ToString();
+                    string authCode = JObject.Parse(web)["data"]["auth_code"].ToString();
+                    Log("生成二维码...");
+                    QRCodeGenerator qrGenerator = new QRCodeGenerator();
+                    QRCodeData qrCodeData = qrGenerator.CreateQrCode(url, QRCodeGenerator.ECCLevel.Q);
+                    QRCode qrCode = new QRCode(qrCodeData);
+                    Bitmap qrCodeImage = qrCode.GetGraphic(7);
+                    qrCodeImage.Save("qrcode.png", System.Drawing.Imaging.ImageFormat.Png);
+                    Log("生成二维码成功:qrcode.png, 请打开并扫描");
+                    parms.Set("auth_code", authCode);
+                    parms.Set("ts", GetTimeStamp(true));
+                    parms.Remove("sign");
+                    parms.Add("sign", GetSign(ToQueryString(parms)));
+                    while (true)
+                    {
+                        Thread.Sleep(1000);
+                        responseArray = webClient.UploadValues(pollUrl, parms);
+                        web = Encoding.UTF8.GetString(responseArray);
+                        string code = JObject.Parse(web)["code"].ToString();
+                        if (code == "86038")
+                        {
+                            LogColor("二维码已过期, 请重新执行登录指令.");
+                            break;
+                        }
+                        else if (code == "86039") //等待扫码
+                        {
+                            continue;
+                        }
+                        else
+                        {
+                            string cc = JObject.Parse(web)["data"]["access_token"].ToString();
+                            Log("登录成功: AccessToken=" + cc);
+                            //导出cookie
+                            File.WriteAllText(Path.Combine(AppContext.BaseDirectory, "BBDownTV.data"), "access_token=" + cc);
+                            File.Delete("qrcode.png");
+                            break;
+                        }
+                    }
+                }
+                catch (Exception e) { LogError(e.Message); }
+            });
+
             rootCommand.Handler = CommandHandler.Create<MyOption>(async (myOption) =>
             {
                 //Console.WriteLine(myOption.ToString());
@@ -160,7 +225,7 @@ private static async Task DoWorkAsync(MyOption myOption)
         {
             Console.BackgroundColor = ConsoleColor.DarkBlue;
             Console.ForegroundColor = ConsoleColor.White;
-            Console.Write("BBDown version 20200810[RC2], Bilibili Downloader.\r\n");
+            Console.Write("BBDown version 20200816[RC3], Bilibili Downloader.\r\n");
             Console.ResetColor();
             Console.Write("请注意:这是一个测试版本,任何BUG请前往以下网址反馈:\r\n" +
                 "https://github.com/nilaoda/BBDown/issues\r\n");
@@ -177,18 +242,24 @@ private static async Task DoWorkAsync(MyOption myOption)
                 string selectPage = myOption.SelectPage;
                 string aid = "";
                 COOKIE = myOption.Cookie;
+                TOKEN = myOption.AccessToken.Replace("access_token=", "");
                 List<string> selectedPages = null;
                 if (!string.IsNullOrEmpty(GetQueryString("p", input)))
                 {
                     selectedPages = new List<string>();
                     selectedPages.Add(GetQueryString("p", input));
                 }
-                
-                if (File.Exists(Path.Combine(AppContext.BaseDirectory, "BBDown.data")))
+
+                if (File.Exists(Path.Combine(AppContext.BaseDirectory, "BBDown.data")) && !tvApi) 
                 {
                     Log("加载本地cookie...");
                     COOKIE = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "BBDown.data"));
                 }
+                if (File.Exists(Path.Combine(AppContext.BaseDirectory, "BBDownTV.data")) && tvApi)
+                {
+                    Log("加载本地token...");
+                    TOKEN = File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "BBDownTV.data"));
+                }
                 Log("获取aid...");
                 aid = await GetAvIdAsync(input);
                 Log("获取aid结束: " + aid);
@@ -312,7 +383,7 @@ private static async Task DoWorkAsync(MyOption myOption)
                     JArray video = null;
 
                     //此处代码简直灾难,后续优化吧
-                    if (webJson.Contains("\"dash\":")) //dash
+                    if (webJson.Contains("\"dash\":[")) //dash
                     {
                         string nodeName = "data";
                         if (webJson.Contains("\"result\":{"))
diff --git a/README.md b/README.md
index 0f6aa2c0f..cd0ce6558 100644
--- a/README.md
+++ b/README.md
@@ -17,23 +17,25 @@ Arguments:
   <url>    视频地址 或 av|bv|BV|ep|ss
 
 Options:
-  -tv, --use-tv-api                  使用TV端解析模式(不支持版权内容)
-  -hevc, --only-hevc                 下载hevc编码
-  -info, --only-show-info            仅解析不下载
-  -hs, --hide-streams                不要显示所有可用音视频流
-  -ia, --interactive                 交互式选择清晰度
-  -mt, --multi-thread                使用多线程下载
-  -p, --select-page <select-page>    选择指定分p或分p范围
-  -c, --cookie <cookie>              设置字符串cookie用以下载网页接口的会员内容
-  --version                          Show version information
-  -?, -h, --help                     Show help and usage information
+  -tv, --use-tv-api                    使用TV端解析模式(不支持版权内容)
+  -hevc, --only-hevc                   下载hevc编码
+  -info, --only-show-info              仅解析不下载
+  -hs, --hide-streams                  不要显示所有可用音视频流
+  -ia, --interactive                   交互式选择清晰度
+  -mt, --multi-thread                  使用多线程下载
+  -p, --select-page <select-page>      选择指定分p或分p范围
+  -c, --cookie <cookie>                设置字符串cookie用以下载网页接口的会员内容
+  -a, --access-token <access-token>    设置access_token用以下载TV接口的会员内容
+  --version                            Show version information
+  -?, -h, --help                       Show help and usage information
 
 Commands:
-  login    通过APP扫描二维码以登录您的账号
+  login      通过APP扫描二维码以登录您的WEB账号
+  logintv    通过APP扫描二维码以登录您的TV账号
 ```
 
 # 功能
-- [x] 番剧下载(Web)
+- [x] 番剧下载(Web|TV)
 - [x] 普通内容下载(Web|TV) `(TV接口可以下载部分UP主的无水印内容)`
 - [x] 多分P自动下载
 - [x] 选择指定分P进行下载
@@ -48,6 +50,9 @@ Commands:
 - [ ] 其他的懒得写了
 
 # 更新日志
+* 2020年8月16日 0:04  
+  支持TV版番剧下载  
+  支持TV二维码登录  
 * 2020年8月10日 20:19  
   修复严重BUG  
 * 2020年8月9日 0:16