You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中Java类下载TikTok视频异常:仅获取HTML文件

问题:TikTok视频下载代码仅获取HTML而非视频文件

我编写了一段用于下载TikTok视频的Java代码,但未能成功下载视频——仅获取了对应页面的HTML文件并命名为tiktok_video.mp4,视频播放器打开报错,文本阅读器可看到完整网页代码。

现有代码

DownloadTask.java

package com.zk.tiktokstudio;

import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class DownloadTask extends AsyncTask<String, Integer, String> {

    private static final String TAG = "DownloadTask";

    @Override
    protected String doInBackground(String... urls) {
        String videoUrl = urls[0];
        String fileName = "tiktok_video.mp4";

        try {
            URL url = new URL(videoUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            int fileLength = connection.getContentLength();
            File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName);
            FileOutputStream fos = new FileOutputStream(outputFile);
            InputStream is = connection.getInputStream();

            byte[] buffer = new byte[1024];
            int len;
            long total = 0;

            while ((len = is.read(buffer)) != -1) {
                total += len;
                publishProgress((int) (total * 100 / fileLength));
                fos.write(buffer, 0, len);
            }

            fos.close();
            is.close();
            return outputFile.getAbsolutePath();

        } catch (Exception e) {
            Log.e(TAG, "Error downloading file: " + e.getMessage());
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        // 更新进度条或UI元素
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // 下载完成后的操作
    }
}

调用代码

String videoUrl = "https://www.tiktok.com/@username/video/1234567890";
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute(videoUrl);

解决方案

核心问题

你传入的是TikTok网页URL,而非真实的视频文件URL,所以代码下载的是网页HTML。需要先从网页源码中提取真实视频地址,再传入下载任务。

具体修改步骤

  1. 添加HTML解析依赖
    在app的build.gradle(Module级别)中添加Jsoup依赖,用于解析TikTok网页:

    dependencies {
        implementation 'org.jsoup:jsoup:1.17.2'
    }
    
  2. 提取真实视频URL
    新增方法从TikTok网页中提取视频的真实播放地址。注意TikTok可能会调整页面结构,以下两种方式可供尝试:

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    
    private String getRealVideoUrl(String webUrl) throws IOException {
        // 设置User-Agent模拟浏览器请求,避免被反爬拦截
        Document doc = Jsoup.connect(webUrl)
                .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
                .get();
    
        // 方式1:从OG元数据中提取视频URL
        Element ogVideo = doc.select("meta[property=\"og:video\"]").first();
        if (ogVideo != null) {
            return ogVideo.attr("content");
        }
    
        // 方式2:从页面的JSON数据中提取(TikTok常用方式)
        Element nextDataScript = doc.select("script[id=\"__NEXT_DATA__\"]").first();
        if (nextDataScript != null) {
            String jsonContent = nextDataScript.html();
            // 这里可以用Gson/Jackson等JSON库解析字符串,提取video的playAddr字段
            // 示例(需引入JSON解析库):
            // JsonObject jsonObject = new Gson().fromJson(jsonContent, JsonObject.class);
            // return jsonObject.getAsJsonObject("props")
            //         .getAsJsonObject("pageProps")
            //         .getAsJsonObject("videoData")
            //         .getAsJsonObject("itemInfo")
            //         .getAsJsonObject("itemStruct")
            //         .getAsJsonObject("video")
            //         .get("playAddr").getAsString();
        }
    
        return null;
    }
    
  3. 修改调用逻辑
    先获取真实视频URL,再传入下载任务:

    String tiktokWebUrl = "https://www.tiktok.com/@username/video/1234567890";
    
    new AsyncTask<String, Void, String>() {
        private static final String TAG = "VideoUrlFetcher";
    
        @Override
        protected String doInBackground(String... strings) {
            try {
                String realVideoUrl = getRealVideoUrl(strings[0]);
                if (realVideoUrl != null) {
                    new DownloadTask().execute(realVideoUrl);
                    return realVideoUrl;
                }
            } catch (IOException e) {
                Log.e(TAG, "Failed to fetch real video URL: " + e.getMessage());
            }
            return null;
        }
    }.execute(tiktokWebUrl);
    
  4. 增强下载任务的兼容性
    在DownloadTask的doInBackground方法中,添加User-Agent请求头,避免视频请求被拦截:

    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    // 添加User-Agent
    connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36");
    connection.connect();
    

注意事项

  • TikTok的页面结构可能会随时变化,若上述提取方式失效,需要重新分析页面源码找到新的视频URL位置。
  • AsyncTask已被Android官方废弃,建议在新项目中使用Coroutines或ExecutorService替代。
  • 确保应用已申请WRITE_EXTERNAL_STORAGE(Android 10及以下)或使用MediaStore(Android 10+)的存储权限。

内容的提问来源于stack exchange,提问作者Mr Zohaib Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:15:10