@akt248

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

kivyを使用したbuildozerによるAndroidアプリケーションのビルドとクラッシュ

解決したいこと

PythonでローカルのミュージックフォルダとYouTubeのある再生リストの動画IDを照合し不足していたら不足している動画をダウンロードするプログラムを作ろうと思いました。
VSCodeで実行すると問題なく起動・動作するのですがapkにビルドしAndroid端末で起動しようとするとLoading...と表示された後アプリがクラッシュしてしまいます。
解決方法を教えてください。

発生している問題・エラー

ビルド時のエラーは無し

該当するソースコード

Python

main.py

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
import logging

from Verification import Search
from Verification import Comparison

from kivy.config import Config

logging.getLogger().setLevel(logging.INFO)

class MyWidget(Widget):
pass

class MyApp(App):
def build(self):
layout = BoxLayout(orientation="vertical", padding=10)
self.log_text = TextInput(
size_hint_x=1.0,
size_hint_y=0.8, # 垂直方向に伸縮する
readonly=True,
multiline=True,
hint_text="Press Search button",
)
self.button = Button(
on_press=self.press,
on_release=self.release,
text="Search",
size_hint_x=1.0,
size_hint_y=0.2, # 垂直方向に伸縮する
)
layout.add_widget(self.log_text)
layout.add_widget(self.button)
return layout

def press(self, btn):
    self.log_text.text += "Search start\n"
    self.button.text = "Sarching..."
    self.log_text.text += "Get local Music files...\n"
    print("Music:")
    global Music_result
    Music_result = Search.Music()
    self.log_text.text += "Get YouTube video_id...\n"
    print("\nyoutube:")

def release(self, btn):
    playlist_id = "PLOEBIV1zsMI9oXXeEti-3AZtyz8u8Znw4"
    YouTube_result = Search.YouTube(playlist_id)
    print(YouTube_result)
    self.log_text.text += "Processing information...\n"
    Comparison.comparison(Music_result, YouTube_result, self)
    self.button.text = "Finished"

if name == "main":

MyApp().run()

Verification.py

import os
import re
from YouTubeDL import Download
from apiclient.discovery import build

API_SERVICE_NAME = "youtube"
API_VERSION = "v3"
API_KEY = "API_KEY"
playlist_id = "PLOEBIV1zsMI9oXXeEti-3AZtyz8u8Znw4"

class Search:
youtube = build(API_SERVICE_NAME, API_VERSION, developerKey=API_KEY)

@classmethod
def Music(cls):
    dir_path = "/home/akito"
    #dir_path = "/storage/D80C-D7EA/Music/Neuro-sama"

    files = os.listdir(dir_path)
    Music_result = files
    print(Music_result)
    return Music_result

@classmethod
def YouTube(cls, playlist_id):
    videos = []

    # プレイリスト内の動画一覧を取得
    request = cls.youtube.playlistItems().list(
        part="contentDetails",
        playlistId=playlist_id,
        maxResults=50,  # 一度に取得する動画の数 (最大50まで)
    )

    while request:
        response = request.execute()
        for item in response.get("items", []):
            videos.append(item["contentDetails"]["videoId"])

        request = cls.youtube.playlistItems().list_next(request, response)

        if request:
            request = cls.youtube.playlistItems().list_next(request, response)

    return videos

search_instance = Search()

class Comparison:
@classmethod
def comparison(cls, Music_result, YouTube_result, self):
# 正規表現パターンをコンパイル
pattern = re.compile(r"[([^]]+)]")
music_string = ", ".join(str(item) for item in Music_result)
matches = pattern.findall(music_string)
Music_result_str = "\n".join(matches) # リストを文字列に変換
YouTube_result_str = "\n".join(YouTube_result) # リストを文字列に変換

    Music_result_set = set(Music_result_str.split("\n"))
    YouTube_result_set = set(YouTube_result_str.split("\n"))
    YouTube_result_set_count = len(YouTube_result_set)
    print("\nTotal videoid count:")
    print(YouTube_result_set_count)

    # YouTubeにはあって、Musicにはないアイテム
    youtube_only = YouTube_result_set - Music_result_set
    common_elements = Music_result_set.intersection(YouTube_result_set)
    result = list(common_elements)
    print("\nVideo count:")
    YouTube_result_set_count_copy = YouTube_result_set_count - len(result)
    print(YouTube_result_set_count_copy)

    print("\nAnd:\n" + str(result) + "\n")
    youtube_only_videoId = len(youtube_only)
    if youtube_only_videoId > 0:
        count = 0
        self.log_text.text += "Downloading...\n"
        for youtube_only_count in youtube_only:
            count = count + 1
            print(youtube_only_count)
            url = "https://www.youtube.com/watch?v=" + youtube_only_count
            Download(count, url)
        self.log_text.text += "Success!"

    else:
        return

YouTubeDL.py

from yt_dlp import YoutubeDL

def Download(count, url):
print(str(count) + "." + url)
ydl_video_opts = {
#動作チェック用
"outtmpl": "D:\Picture" + "\%(title)s[%(id)s].m4a",
#"outtmpl": r"/storage/D80C-D7EA/Music" + "/%(title)s[%(id)s].m4a",
"format": "bestaudio",
}

with YoutubeDL(ydl_video_opts) as ydl:
    result = ydl.download(url)

return result

buildozer.spec
#変更点のみ記載

(list) Application requirements

comma separated e.g. requirements = sqlite3,kivy

requirements = python3,kivy,yt-dlp,google-api-python-client

(list) Permissions

(See https://python-for-android.readthedocs.io/en/latest/buildoptions/#build-options-1 for all the supported syntaxes and properties)

android.permissions = INTERNET,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE

自分で試したこと

main.pyのみでの動作チェック
buildozer.specの編集
⇒何も変わらず

adb logcatの実行
⇒どこを読めば良いか分かりませんでした

0 likes

No Answers yet.

Your answer might help someone💌