Créer un outil de saut automatique d'annonces YouTube avec Python et OCR

Mokuji

1.Tout d'abord 2. Démo 3. Obtenez la chaîne avec OCR 4. Prenez une capture d'écran de Windows 5. Créez une interface graphique avec wxPython 6.Faites exe avec pyinstaller 7. Enfin

introduction

J'ai pensé que ce serait compliqué d'appuyer sur le bouton "Ignorer les annonces" pendant que je regardais YouTube, alors je me suis demandé si je pouvais créer un outil moi-même. J'ai proposé différentes méthodes, mais j'ai pensé qu'il serait plus facile de comprendre la méthode de mise en œuvre plus proche du mouvement humain. J'ai décidé de créer un outil qui reconnaît les caractères avec OCR et clique sur la partie spécifiée.

En conséquence, bien qu'il y ait encore de nombreux problèmes de performances, j'ai pu créer l'outil que j'avais approximativement imaginé. Notez le savoir-faire que vous avez appris lors de sa création. J'espère que cet article aide quelqu'un.

Code source

démo

format de fichier exe. Il cliquera automatiquement sur le lien de saut d'annonce sur youtube.

chunta auto click (fichier d'exécution)

sample2.jpg

Obtenir une chaîne avec OCR

Le traitement OCR a été réalisé en utilisant un logiciel appelé tesseract de python. Pour utiliser tesseract de python sur Windows, l'installation de pip n'est pas bonne, J'ai dû télécharger le module et le mettre dans le chemin. Plus précisément, c'est comme suit.

    #Tesseract dans la variable d'environnement PATH(Outil OCR)Traverser
    os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.abspath(__file__)) + os.sep + RESORSES_FOLDER_NAME

Cette partie est la partie qui passe le chemin pour utiliser tesseract. J'ai mis le chemin vers le dossier RESORSES_FOLDER_NAME dans le répertoire où se trouve le script afin qu'il fonctionne sans problème lorsqu'il est converti en exe. Stockez le module tesseract dans ce dossier RESORSES_FOLDER_NAME.

    # =========================
    #Traitement OCR
    # =========================
    tools = pyocr.get_available_tools()
    
    if len(tools) == 0:
        wx.MessageBox('OCR tool is not installed on the terminal.\n L'outil OCR n'est pas installé sur le terminal.', 'Erreur d'erreur')
        sys.exit(1)
    
    tool = tools[0]
    
    dst = tool.image_to_string(
        cap,
        lang='jpn',
        builder=pyocr.builders.WordBoxBuilder(tesseract_layout=6)
    )

C'est la partie où le texte est réellement obtenu à partir de l'image avec tesseract. Il semble que divers paramètres puissent être spécifiés, mais il a été dit que ce paramètre est bon pour reconnaître le japonais. J'ai aussi essayé un peu et j'ai fini avec ce paramètre.

Prenez une capture d'écran de Windows

J'ai utilisé win32api pour obtenir une capture d'écran sur Windows. Je ne pouvais pas l'installer avec pip install, j'ai donc dû installer win32api séparément.

De plus, un petit traitement spécial a dû être effectué pour prendre en charge le multi-affichage. Le code source de la personne suivante a été utile. (Plutôt, je l'ai utilisé presque tel quel)

Amélioration de l'efficacité commerciale avec python / RPA self-made? Examen partie 5 Comment acquérir la totalité de l'écran dans un environnement multi-moniteurs

#==================================================================
#Acquisition de capture de bureau (compatible avec plusieurs moniteurs)
#Le code de l'URL de référence est utilisé presque tel quel.
# 
# ref https://se.yuttar-ixm.com/multi-monitor-cap/
#==================================================================
def get_capture(flag_gray: bool = True):
    try:
        #Obtenez toute la taille du bureau
        vscreenwidth = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN)
        vscreenheigth = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN)
        vscreenx = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN)
        vscreeny = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN)
        width = vscreenx + vscreenwidth
        height = vscreeny + vscreenheigth
    
        #Obtenir le contexte de l'appareil de bureau
        hwnd = win32gui.GetDesktopWindow() 
        windc = win32gui.GetWindowDC(hwnd)
        srcdc = win32ui.CreateDCFromHandle(windc)
        memdc = srcdc.CreateCompatibleDC()

        #Copier les informations de pixel à partir du contexte de l'appareil, bmp
        bmp = win32ui.CreateBitmap()
        bmp.CreateCompatibleBitmap(srcdc, width, height)
        memdc.SelectObject(bmp)
        memdc.BitBlt((0, 0), (width, height), srcdc, (0, 0), win32con.SRCCOPY)

        #Acquisition / ajustement d'image
        img = np.frombuffer(bmp.GetBitmapBits(True), np.uint8).reshape(height, width, 4)
        if flag_gray is True :
            img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        #Libération
        srcdc.DeleteDC()
        memdc.DeleteDC()
        win32gui.ReleaseDC(hwnd, windc)
        win32gui.DeleteObject(bmp.GetHandle())

        return img
    
    except Exception as err:
        #Échec d'acquisition
        return None

Création d'interface graphique avec wxPython

A l'origine je pensais créer une interface graphique, Cette fois, outre la commodité et la convivialité, il était essentiel de créer une interface graphique. La raison en est que le traitement OCR par tesseract s'est avéré prendre environ 5 à 10 secondes pour une grande image telle qu'une capture en plein écran. Par conséquent, j'ai décidé de demander à l'utilisateur de spécifier la plage à capturer avec l'interface graphique.

    # =========================
    #Traitement lorsque le bouton de réglage de la fenêtre est cliqué
    # =========================
    def onclick_window_btn(self, event):
        #Obtenez une image de capture en plein écran de la taille spécifiée
        self.img = get_capture_img(CAPTURE_IMG_WIDTH)
        
        #Afficher l'image
        self.img_copy = None
        
        #paramètre de nom de fenêtre
        cv2.namedWindow(winname='img')
        
        #Paramètres d'événement de souris
        cv2.setMouseCallback('img', self.draw_rectangle)
        
        #Affichage de l'image
        cv2.imshow('img', self.img)
        
        wx.MessageBox('Choose About Where Your Ads Appear.\n Sélectionnez l'emplacement où la publicité sera affichée.', 'Sélectionnez la zone publicitaire Sélectionnez la zone publicitaire')
    
    # ==================================================
    #Dessinez un rectangle
    # ==================================================
    def draw_rectangle(self, event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            self.flg_drawing = True
            self.ix, self.iy = x, y
        
        elif event == cv2.EVENT_MOUSEMOVE:
            if self.flg_drawing == True:
                self.img_copy = self.img.copy()
                self.img_copy = cv2.rectangle(self.img_copy, (self.ix, self.iy), (x, y), (0, 0, 255), -1)
                cv2.imshow('img', self.img_copy)
        
        elif event == cv2.EVENT_LBUTTONUP:
            self.flg_drawing = False
            self.img_copy = cv2.rectangle(self.img_copy, (self.ix, self.iy), (x, y), (0, 0, 255), -1)
            cv2.imshow('img', self.img_copy)
        
        if event == cv2.EVENT_LBUTTONUP:
            global setting_value
            
            #Augmente vers la droite
            if self.ix < x:
                left = self.ix
                right = x
            else:
                left = x
                right = self.ix
            
            #Augmente à mesure que vous descendez
            if self.iy < y:
                bottom = y
                top = self.iy
            else:
                bottom = self.iy
                top = y
            
            setting_value.top = top
            setting_value.bottom = bottom
            setting_value.left = left
            setting_value.right = right

C'est un processus pour afficher une capture d'écran et dessiner un carré sur l'image avec la souris. Obtenez les coordonnées du rectangle dessiné final et utilisez-les comme champ d'application de la capture.

# ==================================================
# auto_cliquez sur le fil
# ==================================================
class auto_click_Thread(threading.Thread):
    # =========================
    #constructeur
    # =========================
    def __init__(self):
        super(auto_click_Thread, self).__init__()
        
        #Demonized pour terminer le thread lorsque l'appelant se termine
        self.setDaemon(True)
    
    # =========================
    #arrêter le traitement
    # =========================
    def stop(self):
        global setting_value
        
        setting_value.flg_stop = True
    
    # =========================
    #Traitement d'exécution
    # =========================
    def run(self):
        global setting_value
        
        setting_value.flg_stop = False
        
        txt = setting_value.txt
        min_interval_time = setting_value.min_interval_time
        top = int( setting_value.top * (1 / setting_value.rate) )
        bottom = int( setting_value.bottom * (1 / setting_value.rate) )
        left = int( setting_value.left * (1 / setting_value.rate) )
        right = int( setting_value.right * (1 / setting_value.rate) )
        
        click_text(txt, min_interval_time, top, bottom, left, right)

# ==================================================
#début
# ==================================================
def start():
    global exec_thread
    global setting_value
    
    exec_thread = auto_click_Thread()
    exec_thread.start()

# ==================================================
#Arrêtez
# ==================================================
def stop():
    global exec_thread
    
    exec_thread.stop()

C'est la partie qui appelle le traitement OCR à partir de l'interface graphique. En plus de donner un coup de pied à l'interface graphique pour qu'elle ne soit pas occupée Il est démonisé de sorte que si le parent est tué, l'enfant sera également tué. En d'autres termes, le traitement OCR ne s'exécute pas en arrière-plan lorsque l'interface graphique est fermée.

De plus, il est difficile de tuer un thread directement, donc Le traitement d'arrêt a été implémenté en modifiant la valeur de la variable globale référencée par le traitement OCR.

Faire exe avec pyinstaller

Pour une conversion exe normale uniquement, l'utilisateur doit installer tesseract. C'est vraiment gênant, donc je l'ai rendu disponible sans l'installer.

    #Tesseract dans la variable d'environnement PATH(Outil OCR)Traverser
    os.environ["PATH"] += os.pathsep + os.path.dirname(os.path.abspath(__file__)) + os.sep + RESORSES_FOLDER_NAME

Il s'agit d'un processus qui chevauche la partie ci-dessus, mais qui transmet le chemin d'accès au dossier RESORSES_FOLDER_NAME dans le même dossier que le script. Après la conversion en exe, créez un dossier RESORSES_FOLDER_NAME sur le dossier de fichiers exe et stockez le module tesseract dans ce dossier.

En passant, j'ai également essayé la conversion exe d'un fichier avec --onefile de pyinstaller, mais j'ai quitté car il a fallu plus d'une minute pour démarrer.

pyinstaller --clean --icon=chunta_auto_click.ico -n chunta_auto_click chunta_auto_click.py --noconsole

Ce qui précède est la commande lorsqu'elle est convertie en exe.

finalement

Bien qu'il y ait encore de nombreux problèmes de performances, j'ai pu créer l'outil que j'avais en tête. J'étais parfaitement conscient que c'était le bon moment pour des gens comme moi d'utiliser facilement la bibliothèque OCR en collectant des informations en ligne. J'espère que cet article aide quelqu'un.

Code source

chunta auto click (fichier d'exécution)

Recommended Posts

Créer un outil de saut automatique d'annonces YouTube avec Python et OCR
Créer et décrypter du code César avec python
[Python] Python et sécurité-② Outil d'analyse de port réalisé avec Python
Rechercher et télécharger automatiquement des vidéos YouTube avec Python
Obtenez des commentaires sur youtube Live avec [python] et [pytchat]!
Programmation avec Python et Tkinter
Chiffrement et déchiffrement avec Python
Créer un gif 3D avec python3
Obtenez des données Youtube avec python
Gestion de vidéos YouTube avec Python 3
Créez des jeux LCD (16x2) avec Raspberry Pi et Python
Créons un diagramme PRML avec Python, Numpy et matplotlib.
Créez un outil d'analyse vidéo simple avec python wxpython + openCV
python avec pyenv et venv
Créer un répertoire avec python
Fonctionne avec Python et R
Créez des rendez-vous pour le concours AtCoder sur Google Agenda avec Python et GAS
Communiquez avec FX-5204PS avec Python et PyUSB
Briller la vie avec Python et OpenCV
Créer une animation de tracé avec Python + Matplotlib
Robot fonctionnant avec Arduino et python
Installez Python 2.7.9 et Python 3.4.x avec pip.
Créer Awaitable avec l'API Python / C
Modulation et démodulation AM avec python
Grattage avec Python, Selenium et Chromedriver
Grattage avec Python et belle soupe
Créez un environnement virtuel avec Python!
Introduction à Hadoop et MapReduce avec Python
[GUI en Python] PyQt5-Glisser-déposer-
Lire et écrire NetCDF avec Python
J'ai joué avec PyQt5 et Python3
Lire et écrire du CSV avec Python
Intégration multiple avec Python et Sympy
Coexistence de Python2 et 3 avec CircleCI (1.0)
Jeu Sugoroku et jeu d'addition avec Python
Modulation et démodulation FM avec Python
Créer et lire des paquets de messages en Python
[AWS] Créez un environnement Python Lambda avec CodeStar et faites Hello World
Créez votre propre caméra virtuelle avec Python + OpenCV et appliquez des effets originaux
Créez et modifiez des feuilles de calcul dans n'importe quel dossier sur Google Drive avec python
Créez un environnement Python 3 avec pyenv sur Mac et affichez des graphiques Network X
Créez un arbre de décision à partir de 0 avec Python et comprenez-le (5. Entropie des informations)
Communiquez entre Elixir et Python avec gRPC
Construction de pipeline de données avec Python et Luigi
Créer un décorateur de fonction Python avec Class
Surveiller les pannes de Mojo avec Python et Skype
Créez automatiquement la documentation de l'API Python avec Sphinx
Créez wordcloud à partir de votre tweet avec python3
Modulation et démodulation FM avec Python Partie 3
[Automation] Manipulez la souris et le clavier avec Python
Créez une image factice avec Python + PIL.
Authentification sans mot de passe avec RDS et IAM (Python)
Installation de Python et gestion des packages avec pip