Я новичок в Android, пришедший из веб-разработки, поэтому извиняюсь, если у этого вопроса есть очевидный ответ; Google не смог предоставить мне один. У меня есть циклическая анимация, которую я хотел бы превратить в обои для Android, которые можно разместить в магазине приложений.Как вы создаете видео живые обои
Я нашел полезное руководство по созданию базовых живых обоев здесь: http://www.techrepublic.com/blog/android-app-builder/a-bare-bones-live-wallpaper-template-for-android/. После того, как я построил свою собственную версию этого шаблона, я подумал, что могу заменить функцию «draw» тем, что создал медиа-плеер, и сыграл mpg на экране, но мне не повезло найти учебник для этого.
Затем я натолкнулся на это: Android video as a live wallpaper, что указывает на то, что играть на галлон может быть гораздо сложнее и проблематично, чем я предполагал первоначально. Это, по-видимому, дает решение: How to play video as live wallpaper android? Однако для этого требуется использование внешнего API, который, в частности, говорит, что он значительно увеличит сложность, подразумевая, что он должен использоваться только опытными разработчиками.
Итак, я возвращаюсь к основам здесь и спрашиваю: как бы начинающий разработчик создал живые обои из анимации? Использование видеоформата с родным медиаплеером? Нанесение каждого кадра на экран в виде png? Используя свободно доступный api?
EDIT 1:
Поскольку я отвечал я сделал некоторые исследования и разработали два разных приложения, но оба являются неудовлетворительными.
В первом я декодирую каждый кадр (сохраненный как файл PNG) и сохраняя его в массиве растровых изображений. Затем я петлю каждые 50 мс и рисую каждый кадр непосредственно на холст из массива. Этот метод работает относительно гладко, но использование памяти ужасно. Поскольку каждый PNG декодируется и затем сохраняется как растровое изображение, у меня заканчивается память с 1-3 секундами видео (в зависимости от устройства).
Во втором я прочитал каждый кадр в bytearray как PNG-файл. Это позволяет мне хранить их в оперативной памяти для быстрого доступа, но при этом их использование в сжатой памяти минимизируется. Во время цикла я декомпрессию каждого из них на лету от bytearray перед тем, как вытащить его на холст. Этот метод использует менее половины памяти первого. Тем не менее, анимация является нервной, по-видимому, из всех необходимых GC.
Будет ли OpenGL или проигрывать медиаплеером через mpeg лучше, чем эти? Или есть способ оптимизировать один из вышеуказанных методов?
EDIT 2:
У меня доработан метод 2 выше. Раньше я устанавливал задержку в 40 мс в конце функции рисования, чтобы она снова вызывала себя. Однако, поскольку действия декодирования и рисования заняли так много времени, и это было непредсказуемо, это вызвало более 40 мс задержки между кадрами. С тех пор я переместил 40-миллисекундный постдифференцированный вызов в начало процедуры перед обработкой декодирования и рисования. Это привело к гораздо более плавному воспроизведению, хотя ценой около 50% использования процессора было видно. Тем не менее, это до сих пор было проверено только на высокопроизводительном устройстве ICS; Я планирую отдать его на Droid X на следующий день или два, чтобы посмотреть, что произойдет.
Я все еще не убежден, что это лучший метод и был бы признателен за ввод. Я чувствую, что я делаю это неправильно.
EDIT 3: Воспроизведение было относительно гладким на высоком конце устройства, но не на моем Droid X.Я думал, что это может быть связано со всей экстраполяцией, которая должна произойти при отображении изображения с разрешением, отличным от его собственного разрешения. Поэтому я создал код для сохранения каждого кадра в формате jpg при точном разрешении телефона. Это приводит к ошибкам на некоторых устройствах, поэтому я переключился на 1/2 разрешения. Это сработало, хотя использование памяти по-прежнему было высоким.
Я попытался разрешить дальнейшее использование одной фоновой рамки для верхней части 2/3 анимации (которая в основном статична), а затем только сохраненных кадров для нижней трети. Тем не менее, воспроизведение теперь работает намного медленнее, около 10 FPS, даже на высокопроизводительном устройстве. Это, по-видимому, потому, что каждый кадр нуждается в перерисовывании целиком, и теперь на холсте есть два растровых изображения. Хотя использование этого метода очень полезно для использования памяти.
EDIT 4: Был предложение для меня, чтобы включить аппаратное ускорение, которое я понимаю, не может быть сделано при размещении в SurfaceView в живых обоев, как это. Когда я искал, я понял, что графический движок может быть хорошим направлением и попробовать AndEngine. Я преобразовал свои кадры в один гигантский JPG (15000 х 3080 пикселей) и загружать их в спрайт, используя этот код:
waterTexture = new BitmapTextureAtlas(this.getTextureManager(), 15000, 3040, TextureOptions.BILINEAR);
waterRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(waterTexture, this.getAssets(), "wateranimation.jpg", 0, 0, 25, 16);
waterTexture.load();
Я надеялся AndEngine бы каким-то образом разумно загрузки, но вместо этого я только что получил ошибка из памяти с моими обоями, требующими чуть меньше 200 МБ ОЗУ.
Этот проект в настоящее время потребляется более 50 часов, поскольку я считаю, что это была одна строка кода: «backgroundHolder = movie.mpg». Я задал несколько вопросов как на SO, так и на других сайтах о том, как это сделать с относительно небольшим количеством ответов. Это заставляет меня сомневаться в том, что то, что я пытаюсь сделать, даже возможно, несмотря на то, что десять лет назад я смотрел плавные фильмы 800х600 на ПК с долей мощности обработки и памяти даже моего Droid X. Я знаю, аппаратное обеспечение - не проблема. Это мое плохое кодирование или ограничения в Java? Это вообще возможно? Просто узнать, что это невозможно, по крайней мере позволит мне перестать тратить время на это.
Я собираюсь добавить щедрость к этому вопросу.
Вопросы, относящиеся Я начал об этом проекте:
Low framerate writing bitmaps to the canvas
Memory issue when storing images in byteArray
Bitmap.compress results in too large of file
Как в стороне, мне было бы интересно узнать, какой метод обеспечит наилучшую производительность и совместимость. Я читал, что медиаплеер работает только на Android 4+, но я беспокоюсь, что последовательность bmp приведет к слишком низкой производительности. – Nicholas
Вы когда-нибудь находили решение, которым вы были довольны? Была ли библиотека в принятом ответе для вас? – cottonBallPaws
@cottonBallPaws Не один я был «счастлив», но тот, который работает. Тот, в принятом ответе, излишне усложнен (ошибка Android, автор проекта сделал невероятную работу) и имеет ограничения. Я разместил источник для своей версии на своем сайте по адресу http://nightscapecreations.com/mobile/home.cfm#liveWallpapers. Вы можете быть перенаправлены и вам нужно нажать ссылку «посетить мобильный сайт», чтобы установить файл cookie, прежде чем вы сможете его увидеть. Надеюсь, это поможет! – Nicholas