Code Monkey home page Code Monkey logo

Comments (7)

tito avatar tito commented on May 28, 2024

Branch started to fix the issue, but i got weird results. First, we can know the duration of a sound only when it's correctly loaded, any call to the MediaPlayer.getDuration will lead to error like:

E/MediaPlayer(12471): Attempt to call getDuration without a valid mediaplayer
E/MediaPlayer(12471): error (-38, 0)

The question is: should we sync the loading (as pygame does by default) on android? We might get some lag then.
Or should we normalize our Sound API to be async, and then use the Android async feature too?

Also, the duration was correct when playing, but in milliseconds. Then i tried to / 1000. to get seconds, and the division result is just a very weird number. Maybe the java part is wrong.

Anyway, will continue later.

from python-for-android.

tito avatar tito commented on May 28, 2024

This is the branch: https://github.com/kivy/python-for-android/tree/fix-sound-length

from python-for-android.

pkor avatar pkor commented on May 28, 2024

Has there been any change for this? I'm having the same issue and sound length is critical.

from python-for-android.

MichaelCurrie avatar MichaelCurrie commented on May 28, 2024

I'm hitting this error now, and I'm wondering if it has something to do with Python 2 implicitly casting a float to an integer. Just a thought.

p.s. Once this issue is fixed it would be nice to inform this thread about it too.

from python-for-android.

MichaelCurrie avatar MichaelCurrie commented on May 28, 2024

@tito Does this kivy/kivy#2776 mean this is taken care of?

from python-for-android.

MichaelCurrie avatar MichaelCurrie commented on May 28, 2024

As a workaround, I pre-saved all my sound lengths to CSV using the pydub library.

  • All my sounds are .ogg so you'll have to change this if this is not the case for you.
  • I've assumed the media files are all in a folder ../media relative to the location of the below file.
import os, csv
from glob import glob

from pydub import AudioSegment

from flatten import flatten

cur_dir = os.path.dirname(__file__)
media_dir = os.path.join(os.path.dirname(cur_dir), 'media')
sound_paths = (glob(os.path.join(x[0], '*.ogg')) for x in os.walk(media_dir))
# Flatten it, since the lists might contain other lists
south_paths_flattened = list(flatten(sound_paths))

with open('sound_lengths.csv', 'w') as csvfile:
    csvwriter = csv.writer(csvfile, delimiter=',', lineterminator='\n')

    for sound_path in south_paths_flattened:
        print("sound_path: %s" % sound_path)
        try:
            sound = AudioSegment.from_ogg(sound_path)
        except Exception:
            print("Could not load file.")
        else:
            csvwriter.writerow([os.path.normpath(sound_path),
                                str(len(sound) / 1000.)])

Then I load sounds using the static method load of FixedSoundLoader, just the same as if I was going to load the sound with SoundLoader.load.

class FixedSoundLoader(object):
    """
    A custom factory class that substitutes for SoundLoader to avoid issue
    https://github.com/kivy/python-for-android/issues/67

    """
    sound_lengths = {}

    @staticmethod
    def load_sound_lengths():
        with open('sound_lengths.csv', 'r') as csvfile:
            csvreader = csv.reader(csvfile, delimiter=',')
            for row_number, row in enumerate(csvreader):
                print(repr(row))
                FixedSoundLoader.sound_lengths[row[0]] = float(row[1])

    @staticmethod
    def load(sound_file_path):
        sound_file_path = os.path.normpath(sound_file_path)

        if not FixedSoundLoader.sound_lengths:
            FixedSoundLoader.load_sound_lengths()

        sound = SoundLoader.load(sound_file_path)

        try:
            sound_length = FixedSoundLoader.sound_lengths[sound_file_path]
        except KeyError:
            # If we don't have this sound on record in the CSV, hope
            # that the length method actually words
            pass
        else:
            # It's actually the _get_length method we must overrride, as per
            # https://github.com/kivy/kivy/blob/master/
            #                          kivy/core/audio/__init__.py
            sound._get_length = lambda : sound_length

        return sound

from python-for-android.

inclement avatar inclement commented on May 28, 2024

Closing as this issue relates to the old toolchain which is no longer supported. Please open a new issue if you experience this issue with the current master branch.

from python-for-android.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.