| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| <!DOCTYPE html> | ||
| <html> | ||
| <head> | ||
| <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> | ||
| <style type="text/css"> | ||
|
|
||
| body { | ||
| margin: 20px; | ||
| } | ||
|
|
||
| body, td, div, p, li { | ||
| font-family:helvetica, arial, sans-serif; | ||
| font-size:13px; | ||
| line-height:1.3; | ||
| color:#555; | ||
| } | ||
|
|
||
| h1, h2 { | ||
| font-family: helvetica, arial, sans-serif; | ||
| font-weight:normal; | ||
| color: #222; | ||
| margin: 0; | ||
| margin-top: .7em; | ||
| padding: 0; | ||
| line-height: 1.0; | ||
| } | ||
|
|
||
| h1 { | ||
| font-size:22px; | ||
| padding: 0px; | ||
| margin: 0px; | ||
| color:#222; | ||
| } | ||
|
|
||
| h2 { | ||
| font-size:20px; | ||
| padding: 0px; | ||
| margin: 30px 0px 0px; | ||
| color:#222; | ||
| } | ||
|
|
||
| versiontag { | ||
| color: gray; | ||
| } | ||
|
|
||
| a { | ||
| font-size: 14px; | ||
| color: #00A8DF; | ||
| text-decoration: none; | ||
| } | ||
|
|
||
| </style> | ||
| <title>About ServeStream</title> | ||
| </head> | ||
| <body> | ||
| <div id="header" align="center"> | ||
| <p>ServeStream, Version 0.6.8</p> | ||
| <p>Copyright © 2014 William Seemann</p> | ||
| <p>Released under the Apache License, Version 2.0 <a href="LICENSE.html">(View)</a></p> | ||
| </div> | ||
| <h1><b>Libraries</b></h1> | ||
| <h2>drag-sort-listview <a href="https://github.com/bauerca/drag-sort-listview">(Link)</a></h2> | ||
| by Carl A. Bauer, licensed under the Apache 2.0 license | ||
|
|
||
| <h2>FFmpeg <a href="http://www.ffmpeg.org" title="Link">(Link)</a></h2> | ||
| by the FFmpeg team, licensed under the General Public License (GPL) | ||
|
|
||
| <h2>jsoup <a href="http://jsoup.org">(Link)</a></h2> | ||
| by Jonathan Hedley, licensed under the MIT license | ||
|
|
||
| <h2>Java Playlist Parser <a href="http://sourceforge.net/projects/jplaylistparser">(Link)</a></h2> | ||
| by William Seemann, licensed under the Apache 2.0 license | ||
|
|
||
| <h2>FFmpegMediaMetadataRetriever <a href="https://github.com/wseemann/FFmpegMediaMetadataRetriever">(Link)</a></h2> | ||
| by William Seemann, licensed under the Apache 2.0 license | ||
|
|
||
| <h2>FFmpegMediaPlayer <a href="https://github.com/wseemann/FFmpegMediaPlayer">(Link)</a></h2> | ||
| by William Seemann, licensed under the Apache 2.0 license | ||
|
|
||
| <br> | ||
| <br> | ||
| <h1><b>Helpful code</b></h1> | ||
| <h2>AntennaPod <a href="https://github.com/danieloeh/AntennaPod">(Link)</a></h2> | ||
| by Daniel Oeh, licensed under the MIT license | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,92 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project name="ServeStream" default="help"> | ||
|
|
||
| <!-- The local.properties file is created and updated by the 'android' tool. | ||
| It contains the path to the SDK. It should *NOT* be checked into | ||
| Version Control Systems. --> | ||
| <property file="local.properties" /> | ||
|
|
||
| <!-- The ant.properties file can be created by you. It is only edited by the | ||
| 'android' tool to add properties to it. | ||
| This is the place to change some Ant specific build properties. | ||
| Here are some properties you may want to change/update: | ||
| source.dir | ||
| The name of the source directory. Default is 'src'. | ||
| out.dir | ||
| The name of the output directory. Default is 'bin'. | ||
| For other overridable properties, look at the beginning of the rules | ||
| files in the SDK, at tools/ant/build.xml | ||
| Properties related to the SDK location or the project target should | ||
| be updated using the 'android' tool with the 'update' action. | ||
| This file is an integral part of the build system for your | ||
| application and should be checked into Version Control Systems. | ||
| --> | ||
| <property file="ant.properties" /> | ||
|
|
||
| <!-- if sdk.dir was not set from one of the property file, then | ||
| get it from the ANDROID_HOME env var. | ||
| This must be done before we load project.properties since | ||
| the proguard config can use sdk.dir --> | ||
| <property environment="env" /> | ||
| <condition property="sdk.dir" value="${env.ANDROID_HOME}"> | ||
| <isset property="env.ANDROID_HOME" /> | ||
| </condition> | ||
|
|
||
| <!-- The project.properties file is created and updated by the 'android' | ||
| tool, as well as ADT. | ||
| This contains project specific properties such as project target, and library | ||
| dependencies. Lower level build properties are stored in ant.properties | ||
| (or in .classpath for Eclipse projects). | ||
| This file is an integral part of the build system for your | ||
| application and should be checked into Version Control Systems. --> | ||
| <loadproperties srcFile="project.properties" /> | ||
|
|
||
| <!-- quick check on sdk.dir --> | ||
| <fail | ||
| message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." | ||
| unless="sdk.dir" | ||
| /> | ||
|
|
||
| <!-- | ||
| Import per project custom build rules if present at the root of the project. | ||
| This is the place to put custom intermediary targets such as: | ||
| -pre-build | ||
| -pre-compile | ||
| -post-compile (This is typically used for code obfuscation. | ||
| Compiled code location: ${out.classes.absolute.dir} | ||
| If this is not done in place, override ${out.dex.input.absolute.dir}) | ||
| -post-package | ||
| -post-build | ||
| -pre-clean | ||
| --> | ||
| <import file="custom_rules.xml" optional="true" /> | ||
|
|
||
| <!-- Import the actual build file. | ||
| To customize existing targets, there are two options: | ||
| - Customize only one target: | ||
| - copy/paste the target into this file, *before* the | ||
| <import> task. | ||
| - customize it to your needs. | ||
| - Customize the whole content of build.xml | ||
| - copy/paste the content of the rules files (minus the top node) | ||
| into this file, replacing the <import> task. | ||
| - customize to your needs. | ||
| *********************** | ||
| ****** IMPORTANT ****** | ||
| *********************** | ||
| In all cases you must update the value of version-tag below to read 'custom' instead of an integer, | ||
| in order to avoid having your file be overridden by tools such as "android update project" | ||
| --> | ||
| <!-- version-tag: 1 --> | ||
| <import file="${sdk.dir}/tools/ant/build.xml" /> | ||
|
|
||
| </project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project name="custom_rules"> | ||
|
|
||
| <!-- quick check on ndk.dir --> | ||
| <target name="-check-ndk"> | ||
| <fail | ||
| message="ndk.dir is missing. Make sure to put it in local.properties" | ||
| unless="ndk.dir" | ||
| /> | ||
| </target> | ||
|
|
||
| <target name="-check-dependencies"> | ||
| <fail | ||
| message="yasm is missing. Make ensure yasm is installed and present in /usr/bin" | ||
| unless="yasm.exists" | ||
| /> | ||
| </target> | ||
|
|
||
| <target name="native-build" depends="native-clean"> | ||
| <exec executable="${ndk.dir}/ndk-build" failonerror="true" /> | ||
| </target> | ||
|
|
||
| <target name="native-clean"> | ||
| <exec executable="${ndk.dir}/ndk-build" failonerror="true"> | ||
| <arg value="clean" /> | ||
| </exec> | ||
| </target> | ||
|
|
||
| <target name="build-ffmpeg"> | ||
| <exec executable="/bin/sh" dir="." failonerror="true" osfamily="unix"> | ||
| <arg value="scripts/build-ffmpeg.sh" /> | ||
| </exec> | ||
| </target> | ||
|
|
||
| <target name="-pre-build"> | ||
| <available file="/usr/bin/yasm" type="file" property="yasm.exists"/> | ||
| <antcall target="-check-dependencies" /> | ||
| <echo>Building native code...</echo> | ||
| <antcall target="-check-ndk" /> | ||
| <antcall target="build-ffmpeg" /> | ||
| <antcall target="native-build" /> | ||
| <echo>Successfully built native code</echo> | ||
| </target> | ||
|
|
||
| </project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| include $(call all-subdir-makefiles) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| APP_ABI := armeabi armeabi-v7a x86 mips |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| LOCAL_PATH := $(call my-dir) | ||
|
|
||
| include $(CLEAR_VARS) | ||
| LOCAL_MODULE := libavcodec | ||
| LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so | ||
| LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include | ||
| include $(PREBUILT_SHARED_LIBRARY) | ||
|
|
||
| include $(CLEAR_VARS) | ||
| LOCAL_MODULE := libavformat | ||
| LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so | ||
| LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include | ||
| include $(PREBUILT_SHARED_LIBRARY) | ||
|
|
||
| include $(CLEAR_VARS) | ||
| LOCAL_MODULE := libavutil | ||
| LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so | ||
| LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include | ||
| include $(PREBUILT_SHARED_LIBRARY) | ||
|
|
||
| include $(CLEAR_VARS) | ||
| LOCAL_MODULE := libswresample | ||
| LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so | ||
| LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include | ||
| include $(PREBUILT_SHARED_LIBRARY) | ||
|
|
||
| include $(CLEAR_VARS) | ||
| LOCAL_MODULE := libswscale | ||
| LOCAL_SRC_FILES := ffmpeg/$(TARGET_ARCH_ABI)/lib/$(LOCAL_MODULE).so | ||
| LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg/$(TARGET_ARCH_ABI)/include | ||
| include $(PREBUILT_SHARED_LIBRARY) | ||
|
|
||
| LOCAL_PATH:= $(call my-dir) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| LOCAL_PATH:= $(call my-dir) | ||
|
|
||
| include $(CLEAR_VARS) | ||
|
|
||
| LOCAL_MODULE := ffmpeg_mediametadataretriever_jni | ||
| LOCAL_CFLAGS := | ||
| LOCAL_SRC_FILES := net_sourceforge_servestream_media_MediaMetadataRetriever.cpp \ | ||
| mediametadataretriever.cpp \ | ||
| ffmpeg_mediametadataretriever.c | ||
| LOCAL_SHARED_LIBRARIES := libswscale libavcodec libavformat libavutil | ||
| LOCAL_C_INCLUDES := $(LOCAL_PATH)/../ffmpeg/ffmpeg/$(TARGET_ARCH_ABI)/include | ||
| LOCAL_LDLIBS := -llog | ||
|
|
||
| include $(BUILD_SHARED_LIBRARY) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| #ifndef FFMPEG_MEDIAMETADATARETRIEVER_H_ | ||
| #define FFMPEG_MEDIAMETADATARETRIEVER_H_ | ||
|
|
||
| #include <libavcodec/avcodec.h> | ||
| #include <libavformat/avformat.h> | ||
|
|
||
| // Keep these in synch with the constants defined in FFmpegMediaMetadataRetriever.java | ||
| // class. | ||
| typedef enum { | ||
| OPTION_PREVIOUS_SYNC = 0, | ||
| OPTION_NEXT_SYNC = 1, | ||
| OPTION_CLOSEST_SYNC = 2, | ||
| OPTION_CLOSEST = 3, | ||
|
|
||
| // Add more here... | ||
| } Options; | ||
|
|
||
| typedef struct State { | ||
| AVFormatContext *pFormatCtx; | ||
| int audio_stream; | ||
| int video_stream; | ||
| AVStream *audio_st; | ||
| AVStream *video_st; | ||
| } State; | ||
|
|
||
| int set_data_source(State **ps, const char* path); | ||
| const char* extract_metadata(State **ps, const char* key); | ||
| int get_embedded_picture(State **ps, AVPacket *pkt); | ||
| int get_frame_at_time(State **ps, int64_t timeUs, int option, AVPacket *pkt); | ||
| void release(State **ps); | ||
|
|
||
| #endif /*FFMPEG_MEDIAMETADATARETRIEVER_H_*/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| //#define LOG_NDEBUG 0 | ||
| #define LOG_TAG "MediaMetadataRetriever" | ||
|
|
||
| #include <mediametadataretriever.h> | ||
|
|
||
| extern "C" { | ||
| #include "libavcodec/avcodec.h" | ||
| #include "libavformat/avformat.h" | ||
| #include "ffmpeg_mediametadataretriever.h" | ||
| } | ||
|
|
||
| using namespace std; | ||
|
|
||
| MediaMetadataRetriever::MediaMetadataRetriever() | ||
| { | ||
| state = NULL; | ||
| } | ||
|
|
||
| MediaMetadataRetriever::~MediaMetadataRetriever() | ||
| { | ||
| ::release(&state); | ||
| } | ||
|
|
||
| int MediaMetadataRetriever::setDataSource(const char *srcUrl) | ||
| { | ||
| return ::set_data_source(&state, srcUrl); | ||
| } | ||
|
|
||
| int MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option, AVPacket *pkt) | ||
| { | ||
| return ::get_frame_at_time(&state, timeUs, option, pkt); | ||
| } | ||
|
|
||
| const char* MediaMetadataRetriever::extractMetadata(const char *key) | ||
| { | ||
| return ::extract_metadata(&state, key); | ||
| } | ||
|
|
||
| int MediaMetadataRetriever::extractAlbumArt(AVPacket *pkt) | ||
| { | ||
| return ::get_embedded_picture(&state, pkt); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| #ifndef MEDIAMETADATARETRIEVER_H | ||
| #define MEDIAMETADATARETRIEVER_H | ||
|
|
||
| extern "C" { | ||
| #include "libavcodec/avcodec.h" | ||
| #include "libavformat/avformat.h" | ||
| #include "ffmpeg_mediametadataretriever.h" | ||
| } | ||
|
|
||
| using namespace std; | ||
|
|
||
| class MediaMetadataRetriever | ||
| { | ||
| State* state; | ||
| public: | ||
| MediaMetadataRetriever(); | ||
| ~MediaMetadataRetriever(); | ||
| void disconnect(); | ||
| int setDataSource(const char* dataSourceUrl); | ||
| int getFrameAtTime(int64_t timeUs, int option, AVPacket *pkt); | ||
| int extractAlbumArt(AVPacket *pkt); | ||
| const char* extractMetadata(const char* key); | ||
| }; | ||
|
|
||
| #endif // MEDIAMETADATARETRIEVER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,267 @@ | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| //#define LOG_NDEBUG 0 | ||
| #define LOG_TAG "MediaMetadataRetrieverJNI" | ||
|
|
||
| #include <assert.h> | ||
| #include <android/log.h> | ||
| #include <mediametadataretriever.h> | ||
| #include "jni.h" | ||
|
|
||
| extern "C" { | ||
| #include "libavcodec/avcodec.h" | ||
| #include "libavformat/avformat.h" | ||
| } | ||
|
|
||
| using namespace std; | ||
|
|
||
| struct fields_t { | ||
| jfieldID context; | ||
| }; | ||
|
|
||
| static fields_t fields; | ||
| static const char* const kClassPathName = "net/sourceforge/servestream/media/FFmpegMediaMetadataRetriever"; | ||
|
|
||
| void jniThrowException(JNIEnv* env, const char* className, | ||
| const char* msg) { | ||
| jclass exception = env->FindClass(className); | ||
| env->ThrowNew(exception, msg); | ||
| } | ||
|
|
||
| static void process_media_retriever_call(JNIEnv *env, int opStatus, const char* exception, const char *message) | ||
| { | ||
| if (opStatus == -2) { | ||
| jniThrowException(env, "java/lang/IllegalStateException", NULL); | ||
| } else if (opStatus == -1) { | ||
| if (strlen(message) > 230) { | ||
| // If the message is too long, don't bother displaying the status code. | ||
| jniThrowException( env, exception, message); | ||
| } else { | ||
| char msg[256]; | ||
| // Append the status code to the message. | ||
| sprintf(msg, "%s: status = 0x%X", message, opStatus); | ||
| jniThrowException( env, exception, msg); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static MediaMetadataRetriever* getRetriever(JNIEnv* env, jobject thiz) | ||
| { | ||
| // No lock is needed, since it is called internally by other methods that are protected | ||
| MediaMetadataRetriever* retriever = (MediaMetadataRetriever*) env->GetIntField(thiz, fields.context); | ||
| return retriever; | ||
| } | ||
|
|
||
| static void setRetriever(JNIEnv* env, jobject thiz, int retriever) | ||
| { | ||
| // No lock is needed, since it is called internally by other methods that are protected | ||
| MediaMetadataRetriever *old = (MediaMetadataRetriever*) env->GetIntField(thiz, fields.context); | ||
| env->SetIntField(thiz, fields.context, retriever); | ||
| } | ||
|
|
||
| extern "C" JNIEXPORT void JNICALL | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever_setDataSource(JNIEnv *env, jobject thiz, jstring path) { | ||
| //__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "setDataSource"); | ||
| MediaMetadataRetriever* retriever = getRetriever(env, thiz); | ||
| if (retriever == 0) { | ||
| jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); | ||
| return; | ||
| } | ||
|
|
||
| if (!path) { | ||
| jniThrowException(env, "java/lang/IllegalArgumentException", "Null pointer"); | ||
| return; | ||
| } | ||
|
|
||
| const char *tmp = env->GetStringUTFChars(path, NULL); | ||
| if (!tmp) { // OutOfMemoryError exception already thrown | ||
| return; | ||
| } | ||
|
|
||
| // Don't let somebody trick us in to reading some random block of memory | ||
| if (strncmp("mem://", tmp, 6) == 0) { | ||
| jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid pathname"); | ||
| return; | ||
| } | ||
|
|
||
| // Workaround for FFmpeg ticket #998 | ||
| // "must convert mms://... streams to mmsh://... for FFmpeg to work" | ||
| char *restrict_to = strstr(tmp, "mms://"); | ||
| if (restrict_to) { | ||
| strncpy(restrict_to, "mmsh://", 6); | ||
| puts(tmp); | ||
| } | ||
|
|
||
| process_media_retriever_call( | ||
| env, | ||
| retriever->setDataSource(tmp), | ||
| "java/lang/IllegalArgumentException", | ||
| "setDataSource failed"); | ||
|
|
||
| env->ReleaseStringUTFChars(path, tmp); | ||
| tmp = NULL; | ||
| } | ||
|
|
||
| extern "C" JNIEXPORT jbyteArray JNICALL | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever__1getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option) | ||
| { | ||
| //__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "getFrameAtTime"); | ||
| MediaMetadataRetriever* retriever = getRetriever(env, thiz); | ||
| if (retriever == 0) { | ||
| jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); | ||
| return NULL; | ||
| } | ||
|
|
||
| AVPacket packet; | ||
| av_init_packet(&packet); | ||
| jbyteArray array = NULL; | ||
|
|
||
| if (retriever->getFrameAtTime(timeUs, option, &packet) == 0) { | ||
| int size = packet.size; | ||
| uint8_t* data = packet.data; | ||
| array = env->NewByteArray(size); | ||
| if (!array) { // OutOfMemoryError exception has already been thrown. | ||
| __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "getFrameAtTime: OutOfMemoryError is thrown."); | ||
| } else { | ||
| //__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "getFrameAtTime: Got frame."); | ||
| jbyte* bytes = env->GetByteArrayElements(array, NULL); | ||
| if (bytes != NULL) { | ||
| memcpy(bytes, data, size); | ||
| env->ReleaseByteArrayElements(array, bytes, 0); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| av_free_packet(&packet); | ||
|
|
||
| return array; | ||
| } | ||
|
|
||
| extern "C" JNIEXPORT jbyteArray JNICALL | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever_getEmbeddedPicture(JNIEnv *env, jobject thiz) | ||
| { | ||
| //__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "getEmbeddedPicture"); | ||
| MediaMetadataRetriever* retriever = getRetriever(env, thiz); | ||
| if (retriever == 0) { | ||
| jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); | ||
| return NULL; | ||
| } | ||
|
|
||
| AVPacket packet; | ||
| av_init_packet(&packet); | ||
| jbyteArray array = NULL; | ||
|
|
||
| if (retriever->extractAlbumArt(&packet) == 0) { | ||
| int size = packet.size; | ||
| uint8_t* data = packet.data; | ||
| array = env->NewByteArray(size); | ||
| if (!array) { // OutOfMemoryError exception has already been thrown. | ||
| //__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "getEmbeddedPicture: OutOfMemoryError is thrown."); | ||
| } else { | ||
| //__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "getEmbeddedPicture: Found album art."); | ||
| jbyte* bytes = env->GetByteArrayElements(array, NULL); | ||
| if (bytes != NULL) { | ||
| memcpy(bytes, data, size); | ||
| env->ReleaseByteArrayElements(array, bytes, 0); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| av_free_packet(&packet); | ||
|
|
||
| return array; | ||
| } | ||
|
|
||
| extern "C" JNIEXPORT jobject JNICALL | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever_extractMetadata(JNIEnv *env, jobject thiz, jstring jkey) | ||
| { | ||
| //__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "extractMetadata"); | ||
| MediaMetadataRetriever* retriever = getRetriever(env, thiz); | ||
| if (retriever == 0) { | ||
| jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); | ||
| return NULL; | ||
| } | ||
|
|
||
| if (!jkey) { | ||
| jniThrowException(env, "java/lang/IllegalArgumentException", "Null pointer"); | ||
| return NULL; | ||
| } | ||
|
|
||
| const char *key = env->GetStringUTFChars(jkey, NULL); | ||
| if (!key) { // OutOfMemoryError exception already thrown | ||
| return NULL; | ||
| } | ||
|
|
||
| const char* value = retriever->extractMetadata(key); | ||
| if (!value) { | ||
| //__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "extractMetadata: Metadata is not found"); | ||
| return NULL; | ||
| } | ||
| //__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "extractMetadata: value (%s) for keyCode(%s)", value, key); | ||
| env->ReleaseStringUTFChars(jkey, key); | ||
| return env->NewStringUTF(value); | ||
| } | ||
|
|
||
| extern "C" JNIEXPORT void JNICALL | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever_release(JNIEnv *env, jobject thiz) | ||
| { | ||
| __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "release"); | ||
| //Mutex::Autolock lock(sLock); | ||
| MediaMetadataRetriever* retriever = getRetriever(env, thiz); | ||
| delete retriever; | ||
| setRetriever(env, thiz, 0); | ||
| } | ||
|
|
||
| extern "C" JNIEXPORT void JNICALL | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever_native_1finalize(JNIEnv *env, jobject thiz) | ||
| { | ||
| //__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "native_finalize"); | ||
| // No lock is needed, since Java_net_sourceforge_servestream_media_MediaMetadataRetriever_release() is protected | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever_release(env, thiz); | ||
| } | ||
|
|
||
| extern "C" JNIEXPORT void JNICALL | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever_native_1init(JNIEnv *env, jobject thiz) | ||
| { | ||
| __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "native_init"); | ||
| jclass clazz = env->FindClass(kClassPathName); | ||
| if (clazz == NULL) { | ||
| return; | ||
| } | ||
|
|
||
| fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); | ||
| if (fields.context == NULL) { | ||
| return; | ||
| } | ||
|
|
||
| // Initialize libavformat and register all the muxers, demuxers and protocols. | ||
| av_register_all(); | ||
| avformat_network_init(); | ||
| } | ||
|
|
||
| extern "C" JNIEXPORT void JNICALL | ||
| Java_net_sourceforge_servestream_media_FFmpegMediaMetadataRetriever_native_1setup(JNIEnv *env, jobject thiz) | ||
| { | ||
| __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "native_setup"); | ||
| MediaMetadataRetriever* retriever = new MediaMetadataRetriever(); | ||
| if (retriever == 0) { | ||
| jniThrowException(env, "java/lang/RuntimeException", "Out of memory"); | ||
| return; | ||
| } | ||
| setRetriever(env, thiz, (int)retriever); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| LOCAL_PATH:= $(call my-dir) | ||
|
|
||
| include $(CLEAR_VARS) | ||
|
|
||
| LOCAL_MODULE := ffmpeg_mediaplayer_jni | ||
| LOCAL_CFLAGS := | ||
| LOCAL_SRC_FILES := net_sourceforge_servestream_media_FFmpegMediaPlayer.cpp \ | ||
| mediaplayer.cpp \ | ||
| ffmpeg_mediaplayer.c | ||
| LOCAL_SHARED_LIBRARIES := libswresample libavcodec libavformat libavutil | ||
| LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../ffmpeg/ffmpeg/$(TARGET_ARCH_ABI)/include | ||
| LOCAL_LDLIBS := -llog | ||
|
|
||
| include $(BUILD_SHARED_LIBRARY) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| #ifndef ERRORS_H | ||
| #define ERRORS_H | ||
|
|
||
| #include <sys/types.h> | ||
| #include <errno.h> | ||
|
|
||
| using namespace std; | ||
|
|
||
| // use this type to return error codes | ||
| #ifdef HAVE_MS_C_RUNTIME | ||
| typedef int status_t; | ||
| #else | ||
| typedef int32_t status_t; | ||
| #endif | ||
|
|
||
| /* the MS C runtime lacks a few error codes */ | ||
|
|
||
| /* | ||
| * Error codes. | ||
| * All error codes are negative values. | ||
| */ | ||
|
|
||
| // Win32 #defines NO_ERROR as well. It has the same value, so there's no | ||
| // real conflict, though it's a bit awkward. | ||
| #ifdef _WIN32 | ||
| # undef NO_ERROR | ||
| #endif | ||
|
|
||
| enum { | ||
| OK = 0, // Everything's swell. | ||
| NO_ERROR = 0, // No errors. | ||
|
|
||
| UNKNOWN_ERROR = 0x80000000, | ||
|
|
||
| NO_MEMORY = -ENOMEM, | ||
| INVALID_OPERATION = -ENOSYS, | ||
| BAD_VALUE = -EINVAL, | ||
| BAD_TYPE = 0x80000001, | ||
| NAME_NOT_FOUND = -ENOENT, | ||
| PERMISSION_DENIED = -EPERM, | ||
| NO_INIT = -ENODEV, | ||
| ALREADY_EXISTS = -EEXIST, | ||
| DEAD_OBJECT = -EPIPE, | ||
| FAILED_TRANSACTION = 0x80000002, | ||
| JPARKS_BROKE_IT = -EPIPE, | ||
| #if !defined(HAVE_MS_C_RUNTIME) | ||
| BAD_INDEX = -EOVERFLOW, | ||
| NOT_ENOUGH_DATA = -ENODATA, | ||
| WOULD_BLOCK = -EWOULDBLOCK, | ||
| TIMED_OUT = -ETIME, | ||
| UNKNOWN_TRANSACTION = -EBADMSG, | ||
| #else | ||
| BAD_INDEX = -E2BIG, | ||
| NOT_ENOUGH_DATA = 0x80000003, | ||
| WOULD_BLOCK = 0x80000004, | ||
| TIMED_OUT = 0x80000005, | ||
| UNKNOWN_TRANSACTION = 0x80000006, | ||
| #endif | ||
| }; | ||
|
|
||
| // Restore define; enumeration is in "android" namespace, so the value defined | ||
| // there won't work for Win32 code in a different namespace. | ||
| #ifdef _WIN32 | ||
| # define NO_ERROR 0L | ||
| #endif | ||
|
|
||
| // --------------------------------------------------------------------------- | ||
|
|
||
| #endif // ERRORS_H | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| #ifndef FFMPEG_MEDIAPLAYER_H_ | ||
| #define FFMPEG_MEDIAPLAYER_H_ | ||
|
|
||
| #include <libavcodec/avcodec.h> | ||
| #include <libavformat/avformat.h> | ||
| #include <pthread.h> | ||
|
|
||
| #define AUDIO_DATA_ID 1 | ||
| #define MAX_AUDIO_FRAME_SIZE 200000; | ||
|
|
||
| const int NOT_FROM_THREAD = 0; | ||
| const int FROM_THREAD = 1; | ||
|
|
||
| typedef enum media_event_type { | ||
| MEDIA_NOP = 0, // interface test message | ||
| MEDIA_PREPARED = 1, | ||
| MEDIA_PLAYBACK_COMPLETE = 2, | ||
| MEDIA_BUFFERING_UPDATE = 3, | ||
| MEDIA_SEEK_COMPLETE = 4, | ||
| MEDIA_ERROR = 100, | ||
| } media_event_type; | ||
|
|
||
| typedef int media_error_type; | ||
| const media_error_type MEDIA_ERROR_UNKNOWN = 1; | ||
| const media_error_type MEDIA_ERROR_SERVER_DIED = 100; | ||
|
|
||
| typedef enum { | ||
| MEDIA_PLAYER_STATE_ERROR = 0, | ||
| MEDIA_PLAYER_IDLE = 1 << 0, | ||
| MEDIA_PLAYER_INITIALIZED = 1 << 1, | ||
| MEDIA_PLAYER_PREPARING = 1 << 2, | ||
| MEDIA_PLAYER_PREPARED = 1 << 3, | ||
| MEDIA_PLAYER_STARTED = 1 << 4, | ||
| MEDIA_PLAYER_PAUSED = 1 << 5, | ||
| MEDIA_PLAYER_STOPPED = 1 << 6, | ||
| MEDIA_PLAYER_PLAYBACK_COMPLETE = 1 << 7 | ||
| } media_player_states; | ||
|
|
||
| typedef struct State { | ||
| AVFormatContext *pFormatCtx; | ||
| int audio_stream; | ||
| int video_stream; | ||
| AVStream *audio_st; | ||
| AVStream *video_st; | ||
| int buffer_size; | ||
| int loop; | ||
|
|
||
| pthread_t decoder_thread; | ||
| int abort_request; | ||
| int paused; | ||
| int last_paused; | ||
| int seek_req; | ||
| int seek_flags; | ||
| int64_t seek_pos; | ||
| int64_t seek_rel; | ||
| int read_pause_return; | ||
| double audio_clock; | ||
| char filename[1024]; | ||
| char headers[2048]; | ||
|
|
||
| void (*notify_callback) (void*, int, int, int, int); | ||
| int (*init_audio_track_callback) (void*, int, int, int); | ||
| void (*write_audio_callback) (void*, int16_t *, int, int); | ||
| void* clazz; | ||
|
|
||
| char *allow[0]; | ||
| char *block[0]; | ||
| } State; | ||
|
|
||
| void init(State **ps); | ||
| void disconnect(State **ps); | ||
| int setNotifyListener(State **ps, void* clazz, void (*listener) (void*, int, int, int, int)); | ||
| int setInitAudioTrackListener(State **ps, void* clazz, int (*listener) (void*, int, int, int)); | ||
| int setWriteAudioListener(State **ps, void* clazz, void (*listener) (void*, int16_t *, int, int)); | ||
| int setDataSource(State **ps, const char *url, const char *headers); | ||
| int suspend(); | ||
| int resume(); | ||
| int setMetadataFilter(State **ps, char *allow[], char *block[]); | ||
| //int getMetadata(bool update_only, bool apply_filter, Parcel *metadata); | ||
| int get_metadata(State **ps, const char* key, char** value); | ||
| //int setVideoSurface(const sp<Surface>& surface); | ||
| int prepareAsync_l(State **ps); | ||
| int prepare(State **ps); | ||
| int prepareAsync(State **ps); | ||
| int start(State **ps); | ||
| int stop(State **ps); | ||
| int pause(State **ps); | ||
| int isPlaying(State **ps); | ||
| int getVideoWidth(int *w); | ||
| int getVideoHeight(int *h); | ||
| int getCurrentPosition(State **ps, int *msec); | ||
| int getDuration(State **ps, int *msec); | ||
| int seekTo(State **ps, int msec); | ||
| int reset(State **ps); | ||
| int setLooping(State **ps, int loop); | ||
| //void notify(int msg, int ext1, int ext2); | ||
|
|
||
| #endif /*FFMPEG_MEDIAPLAYER_H_*/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| #ifndef MEDIAPLAYER_H | ||
| #define MEDIAPLAYER_H | ||
|
|
||
| #include <Errors.h> | ||
|
|
||
| extern "C" { | ||
| #include "libavcodec/avcodec.h" | ||
| #include "libavformat/avformat.h" | ||
| #include "ffmpeg_mediaplayer.h" | ||
| } | ||
|
|
||
| using namespace std; | ||
|
|
||
| /*enum media_event_type { | ||
| MEDIA_NOP = 0, // interface test message | ||
| MEDIA_PREPARED = 1, | ||
| MEDIA_PLAYBACK_COMPLETE = 2, | ||
| MEDIA_BUFFERING_UPDATE = 3, | ||
| MEDIA_SEEK_COMPLETE = 4, | ||
| MEDIA_ERROR = 100, | ||
| }; | ||
| typedef int media_error_type; | ||
| const media_error_type MEDIA_ERROR_UNKNOWN = 1; | ||
| const media_error_type MEDIA_ERROR_SERVER_DIED = 100; | ||
| enum media_player_states { | ||
| MEDIA_PLAYER_STATE_ERROR = 0, | ||
| MEDIA_PLAYER_IDLE = 1 << 0, | ||
| MEDIA_PLAYER_INITIALIZED = 1 << 1, | ||
| MEDIA_PLAYER_PREPARING = 1 << 2, | ||
| MEDIA_PLAYER_PREPARED = 1 << 3, | ||
| MEDIA_PLAYER_STARTED = 1 << 4, | ||
| MEDIA_PLAYER_PAUSED = 1 << 5, | ||
| MEDIA_PLAYER_STOPPED = 1 << 6, | ||
| MEDIA_PLAYER_PLAYBACK_COMPLETE = 1 << 7 | ||
| };*/ | ||
|
|
||
| // ---------------------------------------------------------------------------- | ||
| // ref-counted object for callbacks | ||
| class MediaPlayerListener | ||
| { | ||
| public: | ||
| virtual void notify(int msg, int ext1, int ext2, int fromThread) = 0; | ||
| virtual int initAudioTrack(int streamType, int sampleRateInHz, int channelConfig, int sessionId, int fromThread) = 0; | ||
| virtual void writeAudio(int16_t *samples, int frame_size_ptr, int fromThread) = 0; | ||
| virtual int setVolume(float leftVolume, float rightVolume) = 0; | ||
| virtual int attachAuxEffect(int effectId) = 0; | ||
| virtual int setAuxEffectSendLevel(float level) = 0; | ||
| }; | ||
|
|
||
| class MediaPlayer | ||
| { | ||
| public: | ||
| MediaPlayer(); | ||
| ~MediaPlayer(); | ||
|
|
||
| void disconnect(); | ||
| status_t setDataSource(const char *url, const char *headers); | ||
| status_t setDataSource(int fd, int64_t offset, int64_t length); | ||
| status_t setMetadataFilter(char *allow[], char *block[]); | ||
| status_t getMetadata(const char *key, char **value); | ||
| //status_t setVideoSurface(const sp<Surface>& surface); | ||
| status_t setListener(MediaPlayerListener *listener); | ||
| MediaPlayerListener * getListener(); | ||
| status_t prepare(); | ||
| status_t prepareAsync(); | ||
| status_t start(); | ||
| status_t stop(); | ||
| status_t pause(); | ||
| bool isPlaying(); | ||
| status_t getVideoWidth(int *w); | ||
| status_t getVideoHeight(int *h); | ||
| status_t seekTo(int msec); | ||
| status_t getCurrentPosition(int *msec); | ||
| status_t getDuration(int *msec); | ||
| status_t reset(); | ||
| status_t setAudioStreamType(int type); | ||
| status_t setLooping(int loop); | ||
| bool isLooping(); | ||
| status_t setVolume(float leftVolume, float rightVolume); | ||
| void notify(int msg, int ext1, int ext, int fromThread); | ||
| status_t setAudioSessionId(int sessionId); | ||
| int getAudioSessionId(); | ||
| status_t setAuxEffectSendLevel(float level); | ||
| int attachAuxEffect(int effectId); | ||
| status_t setNextMediaPlayer(const MediaPlayer* player); | ||
| int initAudioTrack(int sampleRateInHz, int channelConfig, int fromThread); | ||
| void writeAudio(int16_t *samples, int frame_size_ptr, int fromThread); | ||
|
|
||
|
|
||
| private: | ||
| void clear_l(); | ||
| status_t seekTo_l(int msec); | ||
| status_t prepareAsync_l(); | ||
| status_t getDuration_l(int *msec); | ||
| status_t setDataSource(State *state); | ||
|
|
||
| //sp<IMediaPlayer> mPlayer; | ||
| //Mutex mLock; | ||
| //Mutex mNotifyLock; | ||
| //Condition mSignal; | ||
| MediaPlayerListener* mListener; | ||
| void* mCookie; | ||
| media_player_states mCurrentState; | ||
| int mDuration; | ||
| int mCurrentPosition; | ||
| int mSeekPosition; | ||
| bool mPrepareSync; | ||
| status_t mPrepareStatus; | ||
| int mStreamType; | ||
| bool mLoop; | ||
| float mLeftVolume; | ||
| float mRightVolume; | ||
| int mVideoWidth; | ||
| int mVideoHeight; | ||
| int mAudioSessionId; | ||
| float mSendLevel; | ||
| State* state; | ||
| }; | ||
|
|
||
| #endif // MEDIAPLAYER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # To enable ProGuard in your project, edit project.properties | ||
| # to define the proguard.config property as described in that file. | ||
| # | ||
| # Add project specific ProGuard rules here. | ||
| # By default, the flags in this file are appended to flags specified | ||
| # in ${sdk.dir}/tools/proguard/proguard-android.txt | ||
| # You can edit the include path and order by changing the ProGuard | ||
| # include property in project.properties. | ||
| # | ||
| # For more details, see | ||
| # http://developer.android.com/guide/developing/tools/proguard.html | ||
|
|
||
| # Add any project specific keep options here: | ||
|
|
||
| # If your project uses WebView with JS, uncomment the following | ||
| # and specify the fully qualified class name to the JavaScript interface | ||
| # class: | ||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
| # public *; | ||
| #} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # This file is automatically generated by Android Tools. | ||
| # Do not modify this file -- YOUR CHANGES WILL BE ERASED! | ||
| # | ||
| # This file must be checked in Version Control Systems. | ||
| # | ||
| # To customize properties used by the Ant build system edit | ||
| # "ant.properties", and override values to adapt the script to your | ||
| # project structure. | ||
| # | ||
| # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): | ||
| #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt | ||
|
|
||
| # Project target. | ||
| target=android-17 | ||
| android.library.reference.1=../../Android/android-sdk-linux/extras/android/support/v7/appcompat |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <set xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <alpha | ||
| android:interpolator="@android:anim/linear_interpolator" | ||
| android:duration="200" | ||
| android:fromAlpha="0.0" | ||
| android:toAlpha="1.0" /> | ||
| </set> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <set xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <alpha | ||
| android:interpolator="@android:anim/linear_interpolator" | ||
| android:duration="200" | ||
| android:fromAlpha="1.0" | ||
| android:toAlpha="0.0" /> | ||
| </set> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2010 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:state_focused="true" android:state_window_focused="true" | ||
| android:drawable="@drawable/ic_clock_add_alarm_selected" /> | ||
| <item android:state_pressed="true" android:state_window_focused="true" | ||
| android:drawable="@drawable/ic_clock_add_alarm_selected" /> | ||
| <item android:state_focused="false" | ||
| android:drawable="@drawable/ic_clock_add_alarm" /> | ||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:state_pressed="true"> | ||
| <shape> | ||
| <solid android:color="#ff0091c2" /> | ||
| </shape> | ||
| </item> | ||
| <item> | ||
| <shape> | ||
| <solid android:color="@android:color/transparent" /> | ||
| </shape> | ||
| </item> | ||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:state_pressed="true"><shape android:shape="rectangle"> | ||
| <solid android:color="@color/selection_background_color_light" /> | ||
| </shape></item> | ||
| <item android:state_focused="true"><shape android:shape="rectangle"> | ||
| <solid android:color="@color/selection_background_color_light" /> | ||
| </shape></item> | ||
| <item><shape android:shape="rectangle"> | ||
| <solid android:color="@android:color/transparent" /> | ||
| </shape></item> | ||
|
|
||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:state_pressed="true"><shape android:shape="rectangle"> | ||
| <solid android:color="@color/selection_background_color_dark" /> | ||
| </shape></item> | ||
| <item android:state_focused="true"><shape android:shape="rectangle"> | ||
| <solid android:color="@color/selection_background_color_dark" /> | ||
| </shape></item> | ||
| <item><shape android:shape="rectangle"> | ||
| <solid android:color="@android:color/transparent" /> | ||
| </shape></item> | ||
|
|
||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2012 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:drawable="@drawable/btn_player_next_disabled" android:state_enabled="false"/> | ||
| <item android:drawable="@drawable/btn_player_next_normal"/> | ||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2012 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:drawable="@drawable/btn_player_prev_normal" android:state_pressed="true"/> | ||
| <item android:drawable="@drawable/btn_player_prev_normal"/> | ||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2010 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <!-- StateListDrawable used for the small round ImageButtons at the upper | ||
| corners of the in-call onscreen touch UI. --> | ||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
|
|
||
| <item android:state_pressed="true" | ||
| android:drawable="@drawable/btn_strip_trans_right_pressed" /> | ||
|
|
||
| <item android:state_focused="true" | ||
| android:drawable="@drawable/btn_strip_trans_right_selected" /> | ||
|
|
||
| <item android:state_enabled="true" | ||
| android:drawable="@drawable/btn_strip_trans_right_normal" /> | ||
|
|
||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:drawable="@drawable/ic_menu_moreoverflow_normal_holo_dark" /> | ||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:drawable="@drawable/ic_menu_moreoverflow_normal_holo_light" /> | ||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2010 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <selector xmlns:android="http://schemas.android.com/apk/res/android"> | ||
| <item android:state_pressed="true" android:state_window_focused="true" | ||
| android:drawable="@drawable/ic_clock_alarm_selected" /> | ||
| <item android:drawable="@drawable/ic_clock_alarm_on" /> | ||
| </selector> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2012 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > | ||
| <item android:id="@android:id/background"> | ||
| <shape> | ||
| <solid android:color="#ff484848" /> | ||
| </shape> | ||
| </item> | ||
| <item android:id="@android:id/progress"> | ||
| <clip> | ||
| <shape> | ||
| <solid android:color="@color/blue" /> | ||
| </shape> | ||
| </clip> | ||
| </item> | ||
| </layer-list> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2012 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > | ||
| <item | ||
| android:bottom="3.0dip" | ||
| android:left="3.0dip" | ||
| android:right="3.0dip" | ||
| android:top="3.0dip"> | ||
| <shape android:shape="oval" > | ||
| <size | ||
| android:height="10.0dip" | ||
| android:width="10.0dip" /> | ||
|
|
||
| <stroke | ||
| android:width="1.0dip" | ||
| android:color="#3300c8ff" /> | ||
|
|
||
| <solid android:color="#8800c8ff" /> | ||
| </shape> | ||
| </item> | ||
| <item | ||
| android:bottom="10.0dip" | ||
| android:left="10.0dip" | ||
| android:right="10.0dip" | ||
| android:top="10.0dip"> | ||
| <shape android:shape="oval" > | ||
| <size | ||
| android:height="6.0dip" | ||
| android:width="6.0dip" /> | ||
|
|
||
| <stroke | ||
| android:width="1.0dip" | ||
| android:color="#ff00c8ff" /> | ||
|
|
||
| <solid android:color="@color/blue" /> | ||
| </shape> | ||
| </item> | ||
| </layer-list> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,156 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:gravity="center_vertical" | ||
| android:orientation="vertical" | ||
| android:background="@null" > | ||
|
|
||
| <android.support.v4.view.ViewPager | ||
| android:id="@+id/pager" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="0dip" | ||
| android:layout_weight="1" | ||
| android:baselineAligned="false" | ||
| android:orientation="horizontal" /> | ||
|
|
||
| <LinearLayout | ||
| android:id="@+id/player_controller" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:orientation="vertical" > | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="40dip" | ||
| android:paddingLeft="12dip" | ||
| android:paddingRight="12dip" | ||
| android:gravity="center_vertical" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <TextView | ||
| android:id="@+id/position_text" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:paddingRight="6dip" | ||
| android:textSize="12sp" | ||
| android:textColor="#ffbbbbbb" | ||
| android:gravity="right" /> | ||
|
|
||
| <SeekBar | ||
| android:id="@+id/seek_bar" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:gravity="center_vertical" | ||
| android:paddingLeft="9dip" | ||
| android:paddingRight="9dip" | ||
| android:progress="0" | ||
| android:progressDrawable="@drawable/player_progress_drawable" | ||
| android:thumb="@drawable/player_progress_thumb" | ||
| android:thumbOffset="9dip" | ||
| android:maxHeight="2dip" | ||
| android:minHeight="2dip" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/duration_text" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:paddingLeft="6dip" | ||
| android:textSize="12sp" | ||
| android:textColor="#ffbbbbbb" | ||
| android:gravity="left" /> | ||
| </LinearLayout> | ||
|
|
||
| <RelativeLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="60dip" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/shuffle_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentLeft="true" | ||
| android:paddingBottom="20dip" | ||
| android:paddingLeft="12dip" | ||
| android:paddingRight="10dip" | ||
| android:paddingTop="8dip" | ||
| android:background="@null" | ||
| android:src="@drawable/btn_player_shuffle_normal" /> | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:layout_toLeftOf="@+id/repeat_button" | ||
| android:layout_toRightOf="@+id/shuffle_button" | ||
| android:paddingLeft="10dip" | ||
| android:paddingRight="10dip" | ||
| android:gravity="center_vertical" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <net.sourceforge.servestream.button.RepeatingImageButton | ||
| android:id="@+id/previous_button" | ||
| android:background="@null" | ||
| android:paddingBottom="20dip" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:src="@drawable/btn_player_prev" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/play_pause_button" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:paddingBottom="20dip" | ||
| android:background="@null" | ||
| android:src="@drawable/btn_player_play" /> | ||
|
|
||
| <net.sourceforge.servestream.button.RepeatingImageButton | ||
| android:id="@+id/next_button" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:paddingBottom="20dip" | ||
| android:background="@null" | ||
| android:src="@drawable/btn_player_next" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/repeat_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentRight="true" | ||
| android:paddingBottom="20dip" | ||
| android:paddingLeft="10dip" | ||
| android:paddingRight="12dip" | ||
| android:paddingTop="8dip" | ||
| android:background="@null" | ||
| android:src="@drawable/btn_player_repeat_normal" /> | ||
|
|
||
| </RelativeLayout> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </LinearLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:baselineAligned="false" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="0dip" | ||
| android:layout_height="match_parent" | ||
| android:layout_weight="1" | ||
| android:background="@null" | ||
| android:padding="10dip" > | ||
|
|
||
| <net.sourceforge.servestream.utils.CoverView | ||
| android:id="@+id/album_art" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <LinearLayout | ||
| android:id="@+id/player_info" | ||
| android:layout_width="0dip" | ||
| android:layout_height="match_parent" | ||
| android:layout_weight="1" | ||
| android:gravity="center" | ||
| android:orientation="vertical" > | ||
|
|
||
| <TextView | ||
| android:id="@+id/track_number_text" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:singleLine="true" | ||
| android:textColor="#ffa9a9a9" | ||
| android:textSize="13sp" | ||
| android:textStyle="normal" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/trackname" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginLeft="18dip" | ||
| android:layout_marginRight="18dip" | ||
| android:ellipsize="marquee" | ||
| android:singleLine="true" | ||
| android:textColor="#ffffffff" | ||
| android:textSize="17sp" | ||
| android:textStyle="bold" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/artist_and_album" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginLeft="18dip" | ||
| android:layout_marginRight="18dip" | ||
| android:ellipsize="marquee" | ||
| android:singleLine="true" | ||
| android:textColor="#ffa9a9a9" | ||
| android:textSize="13sp" | ||
| android:textStyle="normal" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </LinearLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:id="@android:id/content" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:padding="10dip" > | ||
|
|
||
| <ImageView | ||
| android:id="@+id/overflow_menu_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentRight="true" | ||
| android:layout_centerVertical="true" | ||
| android:src="?attr/list_item_overflow" | ||
| android:contentDescription="" /> | ||
|
|
||
| <TextView | ||
| android:id="@android:id/text2" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_toLeftOf="@+id/overflow_menu_button" | ||
| android:layout_centerVertical="true" | ||
| android:paddingLeft="10dip" | ||
| android:textAppearance="?android:attr/textAppearanceSmall" /> | ||
|
|
||
| <TextView | ||
| android:id="@android:id/text1" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentLeft="true" | ||
| android:layout_toLeftOf="@android:id/text2" | ||
| android:singleLine="true" | ||
| android:ellipsize="end" | ||
| android:textAppearance="?android:attr/textAppearanceLarge" /> | ||
|
|
||
| </RelativeLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:gravity="center_vertical" | ||
| android:orientation="vertical" | ||
| android:background="@null" > | ||
|
|
||
| <android.support.v4.view.ViewPager | ||
| android:id="@+id/pager" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="0dip" | ||
| android:layout_weight="1" | ||
| android:orientation="vertical" /> | ||
|
|
||
| <LinearLayout | ||
| android:id="@+id/player_controller" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:orientation="vertical" > | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="40dip" | ||
| android:paddingLeft="12dip" | ||
| android:paddingRight="12dip" | ||
| android:gravity="center_vertical" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <TextView | ||
| android:id="@+id/position_text" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:paddingRight="6dip" | ||
| android:textSize="12sp" | ||
| android:textColor="#ffbbbbbb" | ||
| android:gravity="right" /> | ||
|
|
||
| <SeekBar | ||
| android:id="@+id/seek_bar" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:gravity="center_vertical" | ||
| android:paddingLeft="9dip" | ||
| android:paddingRight="9dip" | ||
| android:progress="0" | ||
| android:progressDrawable="@drawable/player_progress_drawable" | ||
| android:thumb="@drawable/player_progress_thumb" | ||
| android:thumbOffset="9dip" | ||
| android:maxHeight="2dip" | ||
| android:minHeight="2dip" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/duration_text" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:paddingLeft="6dip" | ||
| android:textSize="12sp" | ||
| android:textColor="#ffbbbbbb" | ||
| android:gravity="left" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <RelativeLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="60dip" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/shuffle_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentLeft="true" | ||
| android:paddingBottom="20dip" | ||
| android:paddingLeft="12dip" | ||
| android:paddingRight="10dip" | ||
| android:paddingTop="8dip" | ||
| android:background="@null" | ||
| android:src="@drawable/btn_player_shuffle_normal" /> | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:layout_toLeftOf="@+id/repeat_button" | ||
| android:layout_toRightOf="@+id/shuffle_button" | ||
| android:paddingLeft="10dip" | ||
| android:paddingRight="10dip" | ||
| android:gravity="center_vertical" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <net.sourceforge.servestream.button.RepeatingImageButton | ||
| android:id="@+id/previous_button" | ||
| android:background="@null" | ||
| android:paddingBottom="20dip" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:src="@drawable/btn_player_prev" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/play_pause_button" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:paddingBottom="20dip" | ||
| android:background="@null" | ||
| android:src="@drawable/btn_player_play" /> | ||
|
|
||
| <net.sourceforge.servestream.button.RepeatingImageButton | ||
| android:id="@+id/next_button" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:paddingBottom="20dip" | ||
| android:background="@null" | ||
| android:src="@drawable/btn_player_next" /> | ||
| </LinearLayout> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/repeat_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentRight="true" | ||
| android:paddingBottom="20dip" | ||
| android:paddingLeft="10dip" | ||
| android:paddingRight="12dip" | ||
| android:paddingTop="8dip" | ||
| android:background="@null" | ||
| android:src="@drawable/btn_player_repeat_normal" /> | ||
|
|
||
| </RelativeLayout> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </LinearLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2014 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:orientation="vertical" > | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="match_parent" | ||
| android:layout_height="0dip" | ||
| android:layout_weight="1" | ||
| android:background="@null" | ||
| android:padding="10dip" > | ||
|
|
||
| <net.sourceforge.servestream.utils.CoverView | ||
| android:id="@+id/album_art" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <LinearLayout | ||
| android:id="@+id/player_info" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginTop="10dip" | ||
| android:gravity="center_horizontal" | ||
| android:orientation="vertical" > | ||
|
|
||
| <TextView | ||
| android:id="@+id/track_number_text" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:paddingTop="5dip" | ||
| android:singleLine="true" | ||
| android:textColor="#ffa9a9a9" | ||
| android:textSize="13sp" | ||
| android:textStyle="normal" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/trackname" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginLeft="12dip" | ||
| android:layout_marginRight="12dip" | ||
| android:ellipsize="marquee" | ||
| android:singleLine="true" | ||
| android:textColor="#ffffffff" | ||
| android:textSize="17sp" | ||
| android:textStyle="bold" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/artist_and_album" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_marginLeft="12dip" | ||
| android:layout_marginRight="12dip" | ||
| android:ellipsize="marquee" | ||
| android:singleLine="true" | ||
| android:textColor="#ffa9a9a9" | ||
| android:textSize="13sp" | ||
| android:textStyle="normal" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </LinearLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:id="@android:id/content" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:padding="10dip" > | ||
|
|
||
| <TextView | ||
| android:id="@android:id/text1" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:paddingRight="5dip" | ||
| android:singleLine="true" | ||
| android:ellipsize="end" | ||
| android:textAppearance="?android:attr/textAppearanceLarge" | ||
| android:layout_alignParentLeft="true" | ||
| android:layout_toLeftOf="@+id/overflow_menu_button" /> | ||
|
|
||
| <TextView | ||
| android:id="@android:id/text2" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:textAppearance="?android:attr/textAppearanceSmall" | ||
| android:layout_below="@android:id/text1" | ||
| android:layout_alignParentLeft="true" | ||
| android:layout_toLeftOf="@id/overflow_menu_button" /> | ||
|
|
||
| <ImageView | ||
| android:id="@id/overflow_menu_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentRight="true" | ||
| android:layout_centerVertical="true" | ||
| android:src="?attr/list_item_overflow" | ||
| android:contentDescription="" /> | ||
|
|
||
| </RelativeLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:id="@+id/nowplaying" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="59.0dip" | ||
| android:gravity="bottom" | ||
| android:orientation="vertical" > | ||
|
|
||
| <View | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="2dip" | ||
| android:background="@drawable/appwidget_divider" /> | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="57.0dip" | ||
| android:gravity="bottom" | ||
| android:orientation="horizontal" | ||
| android:background="?attr/borderless_button" > | ||
|
|
||
| <ImageView | ||
| android:id="@+id/coverart" | ||
| android:layout_width="56.0dip" | ||
| android:layout_height="56.0dip" | ||
| android:scaleType="centerCrop" /> | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="0.0dip" | ||
| android:layout_height="fill_parent" | ||
| android:layout_weight="1.0" | ||
| android:layout_marginLeft="12.0dip" | ||
| android:layout_marginRight="15.0dip" | ||
| android:gravity="left|center" | ||
| android:orientation="vertical" > | ||
|
|
||
| <TextView | ||
| android:id="@+id/title" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:textSize="16.0dip" | ||
| android:textColor="#ffffffff" | ||
| android:singleLine="true" | ||
| android:ellipsize="marquee" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/artist" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:paddingTop="2.0dip" | ||
| android:textSize="12.0dip" | ||
| android:textColor="#ffbbbbbb" | ||
| android:singleLine="true" | ||
| android:ellipsize="marquee" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/previous_button" | ||
| android:layout_width="56.0dip" | ||
| android:layout_height="56.0dip" | ||
| android:gravity="center" | ||
| android:background="?attr/borderless_button" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/play_pause_button" | ||
| android:layout_width="56.0dip" | ||
| android:layout_height="56.0dip" | ||
| android:paddingLeft="5dip" | ||
| android:paddingRight="5dip" | ||
| android:gravity="center" | ||
| android:visibility="gone" | ||
| android:background="?attr/borderless_button" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/next_button" | ||
| android:layout_width="56.0dip" | ||
| android:layout_height="56.0dip" | ||
| android:paddingRight="5dip" | ||
| android:gravity="center" | ||
| android:background="?attr/borderless_button" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </LinearLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:id="@+id/nowplaying" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="59.0dip" | ||
| android:gravity="bottom" | ||
| android:orientation="vertical" > | ||
|
|
||
| <View | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="2dip" | ||
| android:background="@drawable/appwidget_divider" /> | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="57.0dip" | ||
| android:gravity="bottom" | ||
| android:orientation="horizontal" | ||
| android:background="?attr/borderless_button" > | ||
|
|
||
| <ImageView | ||
| android:id="@+id/coverart" | ||
| android:layout_width="56.0dip" | ||
| android:layout_height="56.0dip" | ||
| android:scaleType="centerCrop" /> | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="0.0dip" | ||
| android:layout_height="fill_parent" | ||
| android:layout_weight="1.0" | ||
| android:layout_marginLeft="12.0dip" | ||
| android:layout_marginRight="15.0dip" | ||
| android:gravity="left|center" | ||
| android:orientation="vertical" > | ||
|
|
||
| <TextView | ||
| android:id="@+id/title" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:textSize="16.0dip" | ||
| android:textColor="#ffffffff" | ||
| android:singleLine="true" | ||
| android:ellipsize="marquee" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/artist" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:paddingTop="2.0dip" | ||
| android:textSize="12.0dip" | ||
| android:textColor="#ffbbbbbb" | ||
| android:singleLine="true" | ||
| android:ellipsize="marquee" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/previous_button" | ||
| android:layout_width="56.0dip" | ||
| android:layout_height="56.0dip" | ||
| android:gravity="center" | ||
| android:background="?attr/borderless_button" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/play_pause_button" | ||
| android:layout_width="56.0dip" | ||
| android:layout_height="56.0dip" | ||
| android:paddingLeft="5dip" | ||
| android:paddingRight="5dip" | ||
| android:gravity="center" | ||
| android:visibility="gone" | ||
| android:background="?attr/borderless_button" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/next_button" | ||
| android:layout_width="56.0dip" | ||
| android:layout_height="56.0dip" | ||
| android:paddingRight="5dip" | ||
| android:gravity="center" | ||
| android:background="?attr/borderless_button" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </LinearLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:orientation="vertical" > | ||
|
|
||
| <ListView | ||
| android:id="@android:id/list" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="0dip" | ||
| android:layout_weight="1" /> | ||
|
|
||
| <View | ||
| android:layout_width="match_parent" | ||
| android:layout_height="1dip" | ||
| android:background="?android:attr/dividerVertical" /> | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="48dip" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <Button | ||
| android:id="@+id/alarm_revert" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:background="?android:attr/selectableItemBackground" | ||
| android:text="@string/revert" /> | ||
|
|
||
| <View | ||
| android:layout_width="1dip" | ||
| android:layout_height="fill_parent" | ||
| android:layout_marginBottom="4dp" | ||
| android:layout_marginTop="4dp" | ||
| android:background="?android:attr/dividerVertical" /> | ||
|
|
||
| <Button | ||
| android:id="@+id/alarm_save" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:background="?android:attr/selectableItemBackground" | ||
| android:text="@string/done" /> | ||
|
|
||
| <View | ||
| android:layout_width="1dip" | ||
| android:layout_height="fill_parent" | ||
| android:layout_marginBottom="4dp" | ||
| android:layout_marginTop="4dp" | ||
| android:background="?android:attr/dividerVertical" /> | ||
|
|
||
| <Button | ||
| android:id="@+id/alarm_delete" | ||
| android:layout_width="0dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_weight="1" | ||
| android:background="?android:attr/selectableItemBackground" | ||
| android:text="@string/delete" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </LinearLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| <!-- | ||
| Copyright 2013 The Android Open Source Project | ||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| --> | ||
|
|
||
| <TextView xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:id="@android:id/text1" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:textAppearance="?android:attr/textAppearanceMedium" | ||
| android:gravity="center_vertical" | ||
| android:paddingLeft="16dp" | ||
| android:paddingRight="16dp" | ||
| android:textColor="#fff" | ||
| android:background="?android:attr/activatedBackgroundIndicator" | ||
| android:minHeight="?android:attr/listPreferredItemHeight" /> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:orientation="vertical" > | ||
|
|
||
| <RelativeLayout | ||
| android:id="@+id/footer" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="48dp" | ||
| android:layout_alignParentBottom="true" > | ||
|
|
||
| <View | ||
| android:layout_width="match_parent" | ||
| android:layout_height="1dip" | ||
| android:layout_alignParentTop="true" | ||
| android:background="?android:attr/dividerVertical" /> | ||
|
|
||
| <View | ||
| android:id="@+id/horizontal_divider" | ||
| android:layout_width="1dip" | ||
| android:layout_height="fill_parent" | ||
| android:layout_alignParentTop="true" | ||
| android:layout_centerHorizontal="true" | ||
| android:layout_marginBottom="4dp" | ||
| android:layout_marginTop="4dp" | ||
| android:background="?android:attr/dividerVertical" /> | ||
|
|
||
| <Button | ||
| android:id="@+id/cancel_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentBottom="true" | ||
| android:layout_alignParentLeft="true" | ||
| android:layout_alignParentTop="true" | ||
| android:layout_toLeftOf="@id/horizontal_divider" | ||
| android:background="?android:attr/selectableItemBackground" | ||
| android:text="@android:string/cancel" /> | ||
|
|
||
| <Button | ||
| android:id="@+id/confirm_button" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentBottom="true" | ||
| android:layout_alignParentRight="true" | ||
| android:layout_alignParentTop="true" | ||
| android:layout_toRightOf="@id/horizontal_divider" | ||
| android:background="?android:attr/selectableItemBackground" | ||
| android:text="@string/confirm_label" /> | ||
| </RelativeLayout> | ||
|
|
||
| <ScrollView | ||
| android:layout_width="match_parent" | ||
| android:layout_height="0dp" | ||
| android:layout_above="@id/footer" | ||
| android:layout_alignParentTop="true" | ||
| android:scrollbars="vertical" > | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="match_parent" | ||
| android:layout_height="wrap_content" | ||
| android:orientation="vertical" > | ||
|
|
||
| <TextView | ||
| android:id="@+id/url_text" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_margin="8dp" | ||
| android:focusable="true" | ||
| android:focusableInTouchMode="true" | ||
| android:text="@string/text_url_label" /> | ||
|
|
||
| <EditText | ||
| android:id="@+id/url_edittext" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_margin="8dp" | ||
| android:hint="@string/url_hint" | ||
| android:inputType="textUri" /> | ||
|
|
||
| <CheckBox | ||
| android:id="@+id/save_playlist_entries_checkbox" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:text="@string/store_playlist_entries" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/nickname_text" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_margin="8dp" | ||
| android:focusable="true" | ||
| android:focusableInTouchMode="true" | ||
| android:text="@string/text_nickname_label" /> | ||
|
|
||
| <EditText | ||
| android:id="@+id/nickname_edittext" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" | ||
| android:layout_margin="8dp" | ||
| android:inputType="text" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </ScrollView> | ||
|
|
||
| </RelativeLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <merge xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="fill_parent" | ||
| android:orientation="vertical" > | ||
|
|
||
| <ImageView | ||
| android:id="@+id/coverart" | ||
| android:layout_width="128dip" | ||
| android:layout_height="128dip" | ||
| android:layout_alignBottom="@id/controls" | ||
| android:layout_alignParentLeft="true" | ||
| android:layout_alignParentTop="true" | ||
| android:adjustViewBounds="true" | ||
| android:scaleType="centerCrop" | ||
| android:background="@drawable/albumart_mp_unknown_expanded" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/close" | ||
| android:layout_width="42dip" | ||
| android:layout_height="42dip" | ||
| android:layout_alignParentRight="true" | ||
| android:layout_alignParentTop="true" | ||
| android:scaleType="centerInside" | ||
| android:background="@drawable/bg_notification_button" | ||
| android:src="@drawable/icn_notification_dismiss" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/firstLine" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentTop="true" | ||
| android:layout_toLeftOf="@id/close" | ||
| android:layout_toRightOf="@id/coverart" | ||
| android:duplicateParentState="true" | ||
| android:paddingLeft="10dip" | ||
| android:paddingRight="10dip" | ||
| android:paddingTop="6dip" | ||
| android:singleLine="true" | ||
| android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/secondLine" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_below="@id/firstLine" | ||
| android:layout_toLeftOf="@id/close" | ||
| android:layout_toRightOf="@id/coverart" | ||
| android:duplicateParentState="true" | ||
| android:paddingLeft="10dip" | ||
| android:paddingRight="10dip" | ||
| android:singleLine="true" | ||
| android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/thirdLine" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_below="@id/secondLine" | ||
| android:layout_toLeftOf="@id/close" | ||
| android:layout_toRightOf="@id/coverart" | ||
| android:duplicateParentState="true" | ||
| android:paddingBottom="8dip" | ||
| android:paddingLeft="10dip" | ||
| android:paddingRight="10dip" | ||
| android:singleLine="true" | ||
| android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent" /> | ||
|
|
||
| <TextView | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="1px" | ||
| android:layout_below="@+id/thirdLine" | ||
| android:layout_toRightOf="@id/coverart" | ||
| android:background="#ff424242" /> | ||
|
|
||
| </merge> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="wrap_content" > | ||
|
|
||
| <ImageView | ||
| android:id="@+id/coverart" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentLeft="true" | ||
| android:layout_alignParentTop="true" | ||
| android:adjustViewBounds="true" | ||
| android:maxHeight="64dip" | ||
| android:maxWidth="64dip" | ||
| android:scaleType="centerCrop" | ||
| android:background="@drawable/albumart_mp_unknown_notification" /> | ||
|
|
||
| <LinearLayout | ||
| android:layout_width="fill_parent" | ||
| android:layout_height="64dip" | ||
| android:layout_toRightOf="@id/coverart" | ||
| android:orientation="horizontal" > | ||
|
|
||
| <LinearLayout | ||
| android:id="@id/texts" | ||
| android:layout_width="0dip" | ||
| android:layout_height="64dip" | ||
| android:layout_weight="4" | ||
| android:gravity="center_vertical" | ||
| android:orientation="vertical" | ||
| android:paddingBottom="4dip" | ||
| android:paddingLeft="10dip" | ||
| android:paddingRight="10dip" | ||
| android:paddingTop="6dip" > | ||
|
|
||
| <TextView | ||
| android:id="@+id/title" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:duplicateParentState="true" | ||
| android:singleLine="true" | ||
| android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent.Title" /> | ||
|
|
||
| <TextView | ||
| android:id="@+id/subtitle" | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:duplicateParentState="true" | ||
| android:singleLine="true" | ||
| android:textAppearance="@android:style/TextAppearance.StatusBar.EventContent" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/play_pause" | ||
| android:layout_width="0dip" | ||
| android:layout_height="64dip" | ||
| android:layout_weight="1" | ||
| android:paddingLeft="8dip" | ||
| android:paddingRight="8dip" | ||
| android:scaleType="centerInside" | ||
| android:background="@drawable/bg_notification_button" | ||
| android:src="@android:drawable/ic_media_pause" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/next" | ||
| android:layout_width="0dip" | ||
| android:layout_height="64dip" | ||
| android:layout_weight="1" | ||
| android:paddingLeft="2dip" | ||
| android:paddingRight="2dip" | ||
| android:scaleType="centerInside" | ||
| android:background="@drawable/bg_notification_button" | ||
| android:src="@android:drawable/ic_media_next" /> | ||
|
|
||
| <ImageButton | ||
| android:id="@+id/close" | ||
| android:layout_width="0dip" | ||
| android:layout_height="64dip" | ||
| android:layout_weight="1" | ||
| android:paddingLeft="2dip" | ||
| android:scaleType="centerInside" | ||
| android:background="@drawable/bg_notification_button" | ||
| android:src="@drawable/icn_notification_dismiss" /> | ||
|
|
||
| </LinearLayout> | ||
|
|
||
| </RelativeLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="match_parent" | ||
| android:orientation="vertical" > | ||
|
|
||
| <SeekBar | ||
| android:id="@+id/volume_bar" | ||
| android:layout_width="115dip" | ||
| android:layout_height="wrap_content" | ||
| android:layout_alignParentRight="true" | ||
| android:layout_centerVertical="true" | ||
| android:paddingLeft="9dip" | ||
| android:paddingRight="9dip" | ||
| android:progress="0" | ||
| android:progressDrawable="@drawable/player_progress_drawable" | ||
| android:thumb="@drawable/player_progress_thumb" | ||
| android:thumbOffset="9dip" | ||
| android:maxHeight="2dip" | ||
| android:minHeight="2dip" /> | ||
|
|
||
| </RelativeLayout> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <!-- | ||
| /* | ||
| * ServeStream: A HTTP stream browser/player for Android | ||
| * Copyright 2013 William Seemann | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| --> | ||
|
|
||
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="match_parent" | ||
| android:orientation="vertical" > | ||
|
|
||
| <WebView | ||
| android:id="@+id/about_webview" | ||
| android:layout_width="match_parent" | ||
| android:layout_height="match_parent" /> | ||
|
|
||
| </LinearLayout> |