我有時候會把youtube上一些不錯的影片或好聽的歌集中到播放清單裡面,方便日後觀看,或是在做事情時放出來聽

但常常會遇到某個影片被刪除或者是上傳者的帳號被停權,這時在播放清單裡就只會看到

可能時間久了也忘了原本是什麼東西了,很難再找回來,如果在一開始就將整個播放清單的資訊記錄下來的話,就可以避免這種情況發生

原本是想試著用YouTube Data API v3來實作,但東西實在太多了,一時間無法消化,所以還是用JSON比較簡單,以後有機會再來好好研究YouTube Data API v3的內容

程式目的

從播放清單中抓出每個影片的標題和網址,寫入excel檔案中

前置作業

程式

public class Item {

    /** 影片標題 */
    private String title;
    /** 影片網址 */
    private String videoUrl;
    
    public Item() {
    }
    
    public Item(String title, String videoUrl) {
        this.title = title;
        this.videoUrl = videoUrl;
    }
    
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getVideoUrl() {
        return videoUrl;
    }
    public void setVideoUrl(String videoUrl) {
        this.videoUrl = videoUrl;
    }
}
public static final String baseUrl = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=[播放清單id]&key=[申請好的金鑰]";
public static final String youtubeUrlPrefix = "https://www.youtube.com/watch?v=";
public static List<Item> itemList;

接著分成幾個方法 * 取得資料 * 因為每次最多只能取50筆,所以需呼叫本方法多次,如果後面還有東西,可以從jsonObject中取得nextPageToken,下次呼叫時將其加到baseUrl後方即可查到後面的資料,如果沒東西了,就呼叫產出excel的方法

public void getPlayListItemData(String pageTokenUrl) throws Exception {
    Document doc = Jsoup.connect(baseUrl + pageTokenUrl).ignoreContentType(true).timeout(10 * 1000).get();
    String getJson = doc.text();
    JSONObject jsonObject = (JSONObject) new JSONTokener(getJson).nextValue();
    JSONArray jsonArray = jsonObject.getJSONArray("items");
    for (int i = 0; i < jsonArray.length(); i++) {
        JSONObject item = jsonArray.getJSONObject(i);
        JSONObject snippet = item.getJSONObject("snippet");
        itemList.add(new Item(snippet.getString("title"), youtubeUrlPrefix + snippet.getJSONObject("resourceId").getString("videoId")));
        }
        System.out.println("共抓到" + jsonArray.length() + "個影片");
        if (!jsonObject.isNull("nextPageToken")) {
            String token = jsonObject.getString("nextPageToken");
            getPlayListItemData("&pageToken=" + token);
        } else {
            printExcel();
        }
    }
    /**
     * 產出excel
     * @throws Exception
     */
    public void printExcel() throws Exception {
        // 設定檔名
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_hhmmss");
        String date = dateFormat.format(new Date());
        File file2 = new File("D:" + File.separator + "播放清單資訊" + date + ".xlsx");
        file2.createNewFile();
        OutputStream out = new FileOutputStream(file2);
        XSSFWorkbook workbook = new XSSFWorkbook(); // 新版excel
        XSSFCellStyle cellStyle = setExcelFormat(workbook);
        setExcelContent(workbook, cellStyle);
        // 寫出檔案
        workbook.write(out);
        out.flush();
        out.close();
    }
    
    /**
     * 設定excel樣式
     * @param workbook
     */
    private XSSFCellStyle setExcelFormat(XSSFWorkbook workbook) {
        XSSFFont font = workbook.createFont();
        font.setColor(HSSFColor.BLACK.index);
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setFont(font);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直置中
        cellStyle.setWrapText(true); // 自動換行
        return cellStyle;
    }
    
    /**
     * 放內容
     * @param workbook
     */
    private void setExcelContent(XSSFWorkbook workbook, XSSFCellStyle cellStyle) {
        final int VIDEO_TITLE_SIZE = 100 * 256;
        final int VIDEO_URL_SIZE = 50 * 256;
        // 創建工作表
        XSSFSheet sheet = workbook.createSheet("播放清單資訊");
        sheet.setColumnWidth(0, VIDEO_TITLE_SIZE);
        sheet.setColumnWidth(1, VIDEO_URL_SIZE);
        // 創建標題列
        XSSFRow rowTitle = sheet.createRow(0);
        rowTitle.createCell(0).setCellValue("影片名稱");
        rowTitle.createCell(1).setCellValue("網址");
        XSSFCell cell;
        // 把每列資料放入
        for (int i = 0; i < itemList.size(); i++) {
            Item item = itemList.get(i);
            XSSFRow rowContent = sheet.createRow(i + 1);
            cell = rowContent.createCell(0);
            cell.setCellStyle(cellStyle);
            cell.setCellValue(item.getTitle());
            cell = rowContent.createCell(1);
            cell.setCellStyle(cellStyle);
            cell.setCellValue(item.getVideoUrl());
        }
    }

效果

在main方法中new出一個YoutubePlayListItemGetter呼叫getPlayListItemData(“”),程式整個跑完後,可以在D槽中看到檔案

檔案內容

參考資料

YouTube Data API v3 – How to search YouTube using Java and extract Video ID of the most relevant result?