fawazahmed0 / youtube-uploader

Free youtube video uploader with no limits
MIT License
349 stars 84 forks source link

[feature request]: Schedule videos #64

Open IGuessBlue opened 2 years ago

IGuessBlue commented 2 years ago

Could you add a feature for a uploadAt paramater?

The uploadAt paramater would be an optional paramater indicating at what date the video should be scheduled. This is achievable using YouTube's 'Schedule' functionality.

ReneR97 commented 2 years ago

is there an ETA for this feature. Would really need it

fawazahmed0 commented 2 years ago

Paid support is available for quick resolution & help.

For paid support, please write mail to youtube-uploader@datascraping.pp.ua

fawazahmed0 commented 2 years ago

@IGuessBlue @ReneR97 , You can create a PR, I will be happy to merge it

ndw04 commented 2 years ago

the difficult thing about this is that the date string format is depending on the language used, which means you would have to either change language before uploading or have the user input the date via a string instead of eg. a Date object

winstonzhao commented 1 year ago
    if (videoJSON.schedule) {
            const desiredDate = videoJSON.schedule;
            const scheduleXPath = "//*[normalize-space(text())='Schedule']";
            const scheduleButton = yield page.waitForXPath(scheduleXPath);
            yield scheduleButton.click();
            // calculate dateTime index to month as string e.g. Jan, Feb, Mar
            const dateTimeToMonth = (dateTime) => {
              const month = dateTime.getMonth();
              const monthNames = [
                "Jan",
                "Feb",
                "Mar",
                "Apr",
                "May",
                "Jun",
                "Jul",
                "Aug",
                "Sep",
                "Oct",
                "Nov",
                "Dec",
              ];
              return monthNames[month];
            }
            const dtToStr = (dt) => `${dateTimeToMonth(dt)} ${dt.getDate() + 1}, ${dt.getYear() - 100 + 2000}`;
            const currentDay =  dtToStr(new Date());
            const dayXPath = `//*[normalize-space(text())='${currentDay}']`;
            const dayInput = yield page.waitForXPath(dayXPath);
            yield dayInput.click();
            for (let i = 0; i < 20; ++i)
                yield page.keyboard.press("Backspace")

            yield page.keyboard.type(dtToStr(desiredDate));

            yield page.evaluate(() => {
                document.querySelector("ytcp-form-input-container#time-of-day-container #textbox input").click();
                document.querySelector("ytcp-form-input-container#time-of-day-container #textbox input").click();
            })

            function formatAMPM(date) {
                var hours = date.getHours();
                var minutes = date.getMinutes();
                var ampm = hours >= 12 ? 'PM' : 'AM';
                hours = hours % 12;
                hours = hours ? hours : 12; // the hour '0' should be '12'
                minutes = Math.floor(minutes / 15) * 15;
                minutes = minutes < 10 ? '0'+minutes : minutes;
                var strTime = hours + ':' + minutes + ' ' + ampm;
                return strTime;
            }

            const timeXPath = `//*[normalize-space(text())='${formatAMPM(desiredDate)}']`;
            const timeInput = yield page.waitForXPath(timeXPath);
            yield timeInput.click();
        }

        // Get publish button
        const publishXPath = "//*[@id='done-button']";

If you at that where // Get publish button is in the compiled upload.js file, it seems to work fine. Obviously it's a bit hacky and won't handle other date formats. Basically, you chuck a js Date object as schedule in the videoJSON and it floors the time to 15 minutes.

MarcoLavoro commented 3 months ago
    if (videoJSON.schedule) {
            const desiredDate = videoJSON.schedule;
            const scheduleXPath = "//*[normalize-space(text())='Schedule']";
            const scheduleButton = yield page.waitForXPath(scheduleXPath);
            yield scheduleButton.click();
            // calculate dateTime index to month as string e.g. Jan, Feb, Mar
            const dateTimeToMonth = (dateTime) => {
              const month = dateTime.getMonth();
              const monthNames = [
                "Jan",
                "Feb",
                "Mar",
                "Apr",
                "May",
                "Jun",
                "Jul",
                "Aug",
                "Sep",
                "Oct",
                "Nov",
                "Dec",
              ];
              return monthNames[month];
            }
            const dtToStr = (dt) => `${dateTimeToMonth(dt)} ${dt.getDate() + 1}, ${dt.getYear() - 100 + 2000}`;
            const currentDay =  dtToStr(new Date());
            const dayXPath = `//*[normalize-space(text())='${currentDay}']`;
            const dayInput = yield page.waitForXPath(dayXPath);
            yield dayInput.click();
            for (let i = 0; i < 20; ++i)
                yield page.keyboard.press("Backspace")

            yield page.keyboard.type(dtToStr(desiredDate));

            yield page.evaluate(() => {
                document.querySelector("ytcp-form-input-container#time-of-day-container #textbox input").click();
                document.querySelector("ytcp-form-input-container#time-of-day-container #textbox input").click();
            })

            function formatAMPM(date) {
                var hours = date.getHours();
                var minutes = date.getMinutes();
                var ampm = hours >= 12 ? 'PM' : 'AM';
                hours = hours % 12;
                hours = hours ? hours : 12; // the hour '0' should be '12'
                minutes = Math.floor(minutes / 15) * 15;
                minutes = minutes < 10 ? '0'+minutes : minutes;
                var strTime = hours + ':' + minutes + ' ' + ampm;
                return strTime;
            }

            const timeXPath = `//*[normalize-space(text())='${formatAMPM(desiredDate)}']`;
            const timeInput = yield page.waitForXPath(timeXPath);
            yield timeInput.click();
        }

        // Get publish button
        const publishXPath = "//*[@id='done-button']";

If you at that where // Get publish button is in the compiled upload.js file, it seems to work fine. Obviously it's a bit hacky and won't handle other date formats. Basically, you chuck a js Date object as schedule in the videoJSON and it floors the time to 15 minutes.

I not understand, Where I have to put this code to let it schedule a video?