I wanted to update the song metadata fields of Track, album, genre, artist and song cover image like Musicmatch.
I tried to look for the code to update the meta couldn't find any solutions.
Your question isn't about a problem and is not detailed. But I can give you a great Media Player from google samples named UAMP(Universal Android Media Player) with handle all about android media player. Link
UAMP uses a MediaMetadataCompat to update the song metadata like below code segment.
fun MediaMetadataCompat.Builder.from(jsonMusic: JsonMusic): MediaMetadataCompat.Builder {
// The duration from the JSON is given in seconds, but the rest of the code works in
// milliseconds. Here's where we convert to the proper units.
val durationMs = TimeUnit.SECONDS.toMillis(jsonMusic.duration)
id = jsonMusic.id
title = jsonMusic.title
artist = jsonMusic.artist
album = jsonMusic.album
duration = durationMs
genre = jsonMusic.genre
mediaUri = jsonMusic.source
albumArtUri = jsonMusic.image
trackNumber = jsonMusic.trackNumber
trackCount = jsonMusic.totalTrackCount
flag = MediaItem.FLAG_PLAYABLE
// To make things easier for *displaying* these, set the display properties as well.
displayTitle = jsonMusic.title
displaySubtitle = jsonMusic.artist
displayDescription = jsonMusic.album
displayIconUri = jsonMusic.image
// Add downloadStatus to force the creation of an "extras" bundle in the resulting
// MediaMetadataCompat object. This is needed to send accurate metadata to the
// media session during updates.
downloadStatus = STATUS_NOT_DOWNLOADED
// Allow it to be used in the typical builder style.
return this
}
By this component, you can update song data in the notification, lock screen, and home screen.
To update the metadata of a song we can do by using ID3 tags. We can update these using Mp3Tag editor - https://github.com/aminb/id3r
, MyID3() editor - https://github.com/ericfarng/jid3lib
and Jaudiotagger - https://github.com/Adonai/jaudiotagger.
Mp3Tag editor - Only Mp3 song type is supported
MyID3 editor - Can edit song easily but not all field provided is updated
Jaudiotagger - This supports
Mp3,
Flac,
OggVorbis,
Mp4,
Aiff,
Wav,
Wma,
Dsf
audio formats
It updated data without any issue
try {
val audioFile = AudioFileIO.read(file)
val tag = audioFile?.tagOrCreateAndSetDefault
tag?.setField(FieldKey.ARTIST, binding?.tiArtist?.text?.toString())
tag?.setField(FieldKey.ALBUM, binding?.tiAlbum?.text?.toString())
tag?.setField(FieldKey.GENRE, binding?.tiGenre?.text?.toString())
tag?.setField(FieldKey.TITLE, binding?.tiTrack?.text?.toString())
// Handle the image setting
try {
val pfd = contentResolver.openFileDescriptor(imageUri, "r") ?: return
val fis = FileInputStream(pfd.fileDescriptor)
val imgBytes = JavaUtils.readFully(fis)
val cover = AndroidArtwork()
cover.binaryData = imgBytes
cover.mimeType = ImageFormats.getMimeTypeForBinarySignature(byteArray)
cover.description = ""
cover.pictureType = PictureTypes.DEFAULT_ID
tag?.deleteArtworkField()
tag?.setField(cover)
fis.close()
// to do check the file write option for both internal and external card
// Handle the Storage Access FrameWork API if song is from SD card
if (audioFile?.file?.let { SafUtils.isSafNeeded(it, this) } == true) {
// Handle writing into SD card
// Check if SAF permission is provided then only we can update metadata
// If SAF Permission is not provided. EACCESS : Permission Denied error is displayed
// After the permission success then only we can update meta.
writeIntoSDCard()
} else {
// Handle writing into internal card
writeInInternalStorage()
}
} catch (e: Exception) { }
} catch (e: Exception) {
// Show error on failure while writing
} catch (e: Error) {
// Show error on failure while writing
}
Writing the metadata
// After update refresh the file else the changes will not be reflected
AudioFileIO.write(audioFile)
MediaScannerConnection.scanFile(context, arrayOf(file?.absolutePath ?: ""), null, null)
how to play multiple videos one after the another in xamarin cross platform form c#
I have tried using list, array but the problem is that the last video only gets played, rest videos just doesnt play.
MediaQueue mq = new MediaQueue();
MediaFile mf = new MediaFile();
if (PlayStopButtonText.Text == "Play")
{
/*string videoUrl1 = "https://archive.org/download/BigBuckBunny_328/BigBuckBunny_512kb.mp4";
string videoUrl = "https://sec.ch9.ms/ch9/e68c/690eebb1-797a-40ef-a841-c63dded4e68c/Cognitive-Services-Emotion_high.mp4";
CrossMediaManager.Current.Play(videoUrl,MediaFileType.Video,ResourceAvailability.Remote);
//CrossMediaManager.Current.PlayNext();*/
mf.Url = videoUrll;
mf.Type = MediaFileType.Video;
mq.Insert(0,mf);
mf.Url = videoUrl;
mf.Type = MediaFileType.Video;
mq.Insert(1, mf);
foreach(var item in mq)
{
CrossMediaManager.Current.Play(item.Url,MediaFileType.Video);
}
}
i was made a simple video playback for android application with adobe flash using action script 3, where a flvplayback access playlist from xml file "xmlVideoPlayer.xml", and i put in folder "media/PustakaXML/xmlVideoPlayer.xml" where parent folder same with myfile.fla (project file).
can somebody help me, how to ; if i put myxml file on SDCARD on android mobile. so if i publish it, to APK, and instal on android mobile, the aplication can access myxml file on SDCARD.
below the script on my adobe flash actionscript code.
import fl.video.*;
import flash.events.Event;
import flash.net.*;
// Set Variables
var flvControl:FLVPlayback = display;
var flvIndex:Number = 0;
var loopAtEnd:Boolean = true;
// Load XML file...
var xmlList:XML;
var xmlPath:String = "media/PustakaXML/xmlVideoPlayer.xml";
//HELP HERE if file put in SDCARD
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.load(new URLRequest(xmlPath));
// Receive the XML and load the first video
function xmlLoadedHandler(event:Event):void
{
// Save XML
xmlList = new XML(xmlLoader.data);
// Set video (Start)
flvControl.source = xmlList.video[0];
}
xmlLoader.addEventListener(Event.COMPLETE, xmlLoadedHandler);
// 3. Handle video completion (load next video)
function completeHandler(event:fl.video.VideoEvent):void
{
// Get next item in list
flvIndex++;
// Validate index
if( flvIndex == xmlList.video.length() ){
if( loopAtEnd ){
flvIndex = 0;
}
else{
return;
}}
// Load next video
flvControl.source = xmlList.video[flvIndex];
}
flvControl.addEventListener(fl.video.VideoEvent.COMPLETE, completeHandler);
i am sorry my English no good enough...
I'm following these (1, 2) guides to create a sender Android application for Chromecast and I'm only interested in sending pictures.
There are a lot of informaton and samples how to cast Text, Audio and Video. But not a single word how to that with Pictures.
I belive in power of stackoferflow and someone should've faced such problem. Please give some good sample or tutorial. All I need is guide to cast fullscreen picture using Media Router and its features.
Thats how I was sending text message using custom channel:
/**
* Send a text message to the receiver
*/
private void sendMessage(String message) {
if (mApiClient != null && mSmartBusChannel != null) {
try {
Cast.CastApi.sendMessage(mApiClient,
mSmartBusChannel.getNamespace(), message)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status result) {
if (!result.isSuccess()) {
Log.e(TAG, "Sending message failed");
}
}
});
} catch (Exception e) {
Log.e(TAG, "Exception while sending message", e);
}
} else {
Toast.makeText(this, message, Toast.LENGTH_SHORT)
.show();
}
}
Video is sending using RemotePlaybackClient.. Okay, what's about pictures?
Much thanks for any help.
EDIT:
I have found out method (on this blog) of how it is possible to send pictures from local storage. And yeah, that doesn't seem really working.
public final void openPhotoOnChromecast(String title, String url, String ownerName, String description) {
try {
Log.d(TAG, "openPhotoOnChromecast: " + url);
JSONObject payload = new JSONObject();
payload.put(KEY_COMMAND, "viewphoto");
payload.put("fullsizeUrl", url);
payload.put("ownerName", ownerName);
payload.put("title", title);
payload.put("description", description);
sendMessage(payload);
} catch (JSONException e) {
Log.e(TAG, "Cannot parse or serialize data for openPhotoOnChromecast", e);
} catch (IOException e) {
Log.e(TAG, "Unable to send openPhotoOnChromecast message", e);
} catch (IllegalStateException e) {
Log.e(TAG, "Message Stream is not attached", e);
}
}
P.S. this method uses sendMessage(...) from these libraries (from gradle):
compile files('libs/commons-io-2.4.jar')
compile files('libs/GoogleCastSdkAndroid.jar')
Looking here: Examples using CastCompanionLibrary to simply display an image There are really three options for sending images to a Chromecast.
You can encode the image in a base64 string and send it over a
data channel to the receiver. If it is too big, you can split it up
and send it across in multiple messages. This is a really poor use
of the cast technology and really you shouldn't do this, but it is
possible.
You could simply send a url to the Chromecast device and grab it
from your sever inside the receiver app. This the the recommended
way to send photos across to the Chromecast
If you aren't downloading your images from a server you could set
up your own server running inside your client Android app and send a
url to the receiver to grab it from there. This is rather
complicated for sending images across, but is a far more robust
option than option 1.
The goal of Chromecast, according to Google, is to stream content from the cloud, which is why there isn't really any native support for sending local images. Developers should be encouraged to load images on the receiver application from a server.
Here is a pretty well documented example of how to make a slideshow / serve images from a local folder in Linux / Ubuntu:
https://github.com/sbow/pyCast
The directory / file types are specified at runtime - or default values can be used.
The code makes use of the module pychromecast & generates a simple webserver to make the images available to the Chromecast.
Code Examples
Create a local webserver
# Start webserver for current directory
def startServer(args, PORT=8000):
os.chdir(args.directory)
handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), handler) as httpd:
print("Server started at localhost:" + str(PORT))
httpd.serve_forever()
# Start new thread for webserver
daemon = threading.Thread(name='daemon_server',
target=startServer,
args=(args, PORT))
daemon.setDaemon(True) # Set as a daemon so it will be killed once the main thread is dead.
daemon.start()
Build URL's For Local Images
# Build uri of first image for slideshow. This is sent to the chromecast. This
# ends up being a mash up of the host ip address, the webserver port, and the
# file name of the image to be displayed.
fileName = os.path.basename(filesAndPath[nStartFile])
fileUrl = urllib.parse.quote(fileName)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ipAddr = s.getsockname()[0]
fileUri = 'http://'+ipAddr+':'+'8000/'+fileUrl
Setup Chromecast
# -- Setup chromecast --
# List chromecasts on the network, but don't connect
services, browser = pychromecast.discovery.discover_chromecasts()
# Shut down discovery
pychromecast.discovery.stop_discovery(browser)
chromecasts, browser = pychromecast.get_listed_chromecasts(
friendly_names=[args.cast]
)
if not chromecasts:
print(f'No chromecast with name "{args.cast}" discovered')
sys.exit(1)
cast = chromecasts[0]
# Start socket client's worker thread and wait for initial status update
cast.wait()
print(f'Found chromecast with name "{args.cast}", attempting to play "{args.url}"')
cast.media_controller.play_media(fileUri, MEDIA_TAG)
# Wait for player_state PLAYING
player_state = None
has_played = False
# -- end Setup chromecast --
Infinite loop serving images from folder
# Enter the infinite loop where successive images are displayed via the
# chromecast, by sending it image uri's served by our scripts webserver,
# linking the chromecast to images in our directory.
iPhoto = nStartFile
iPhotoMax = nFiles-1
while True:
try:
if player_state != cast.media_controller.status.player_state:
player_state = cast.media_controller.status.player_state
print("Player state:", player_state)
if player_state == "PLAYING":
has_played = True
if cast.socket_client.is_connected and has_played and player_state != "PLAYING":
has_played = False
cast.media_controller.play_media(args.url, "audio/mp3")
time.sleep(args.pause)
if args.do_random:
nRandom = random.random()*nFiles
iPhoto = round(nRandom)
else:
iPhoto = iPhoto + 1
if iPhoto > iPhotoMax:
iPhoto = 0
fileName = os.path.basename(filesAndPath[iPhoto])
fileUrl = urllib.parse.quote(fileName)
fileUri = 'http://'+ipAddr+':'+'8000/'+fileUrl
cast.media_controller.play_media(fileUri, MEDIA_TAG)
except KeyboardInterrupt:
break
Full program pyCast.py
"""
Play a slideshow on the chromecast
This program allows the user to cast images to their chromecast.
The images are of a particular type ie: ".JPEG" or ".jpg" or ".png",
and contained in a single folder. These parameters are provided,
among others, at command line invocation - or through tuning of
the default parameters below.
Arguments
__________
--show-debug : (none)
Show debugging information. False if not provided.
--do-random : (none)
Select image order at random. Ls order if not provided.
--media-flag : '*.jpeg'
Indicate via a command line regex file type to show
--media-tag : 'image/jpeg'
Indicate http object type
--cast : 'MyKitchenChromecast'
Provide friendly name of chromecast
--directory : '/home/barack/SecretPix'
Provide absolute path to directory for slideshow
--pause : 69
Number of seconds to hold each image in slideshow
Returns
_______
does not return. Ctrl-C to exit, or launch with "&" and kill process
Examples
______
python pyCast.py --show-debug --media-flag '*.JPEG' --media-tag 'image/jpeg'
--cast 'MyChromecast' --directory '/home/dorthy/OzGirlSummerPics' --do-random
"""
# pylint: disable=invalid-name
import argparse
import logging
import sys
import time
import pychromecast
import pprint
import glob
import os
import urllib.parse
import socket
import http.server
import socketserver
import threading
import random
# Authorship information
__author__ = "Shaun Bowman"
__copyright__ = "Copywrong 2022, Mazeltough Project"
__credits__ = ["SoManyCopyPastes... sorry i dont know the names", "Mom"]
__license__ = "MIT"
__version__ = "0.420.69"
__maintainer__ = "Shaun Bowman"
__email__ = "dm#me.com"
__status__ = "AlphaAF"
# Change to the friendly name of your Chromecast
CAST_NAME = 'ShaunsOfficeMonitor'
# Set webserver port
PORT = 8000
# Set time for photo
PAUSE = 120
# Set media type
MEDIA_FLAG = "*.JPEG"
MEDIA_TAG = "image/jpeg"
# Change to an audio or video url
MEDIA_URL ="http://192.168.0.222:8000/Screenshot%20from%202021-01-24%2023-11-40.png"
MEDIA_DIR = "./"
parser = argparse.ArgumentParser(
description="Play a slideshow on Chromecast using all images of a given "+
"type in a given directory."
)
parser.add_argument("--show-debug", help="Enable debug log", action="store_true")
parser.add_argument("--do-random", help="Pick media in dir at random, default false",
action="store_false")
parser.add_argument(
"--media-flag", help="Media flag like *.JPEG or *.png", default=MEDIA_FLAG
)
parser.add_argument(
"--media-tag", help="Media tag like 'image/jpeg' or 'image/png'",
default=MEDIA_TAG
)
parser.add_argument(
"--pause", help="Number of seconds per photograph during slideshow",
default=PAUSE
)
parser.add_argument(
"--cast", help='Name of cast device (default: "%(default)s")', default=CAST_NAME
)
parser.add_argument(
"--url", help='Media url (default: "%(default)s")', default=MEDIA_URL
)
parser.add_argument(
"--directory", help='Directory containing media to cast', default=MEDIA_DIR
)
args = parser.parse_args()
if args.show_debug:
logging.basicConfig(level=logging.DEBUG)
# Start webserver for current directory
def startServer(args, PORT=8000):
os.chdir(args.directory)
handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), handler) as httpd:
print("Server started at localhost:" + str(PORT))
httpd.serve_forever()
# Start new thread for webserver
daemon = threading.Thread(name='daemon_server',
target=startServer,
args=(args, PORT))
daemon.setDaemon(True) # Set as a daemon so it will be killed once the main thread is dead.
daemon.start()
# Wait for stuff... maybe useless
time.sleep(2)
# Get list of files of specific type, in specific directory
pprint.pprint(glob.glob(args.directory+"/"+MEDIA_FLAG))
filesAndPath = glob.glob(args.directory+"/"+MEDIA_FLAG)
nFiles = len(filesAndPath)
if (nFiles==0):
pprint.pprint("Error: No files found")
sys.exit(1)
# Select starting point for slideshow
random.seed()
nRandom = random.random()*nFiles
nStartFile = round(nRandom)
# Build uri of first image for slideshow. This is sent to the chromecast. This
# ends up being a mash up of the host ip address, the webserver port, and the
# file name of the image to be displayed.
fileName = os.path.basename(filesAndPath[nStartFile])
fileUrl = urllib.parse.quote(fileName)
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
ipAddr = s.getsockname()[0]
fileUri = 'http://'+ipAddr+':'+'8000/'+fileUrl
# -- Setup chromecast --
# List chromecasts on the network, but don't connect
services, browser = pychromecast.discovery.discover_chromecasts()
# Shut down discovery
pychromecast.discovery.stop_discovery(browser)
chromecasts, browser = pychromecast.get_listed_chromecasts(
friendly_names=[args.cast]
)
if not chromecasts:
print(f'No chromecast with name "{args.cast}" discovered')
sys.exit(1)
cast = chromecasts[0]
# Start socket client's worker thread and wait for initial status update
cast.wait()
print(f'Found chromecast with name "{args.cast}", attempting to play "{args.url}"')
cast.media_controller.play_media(fileUri, MEDIA_TAG)
# Wait for player_state PLAYING
player_state = None
has_played = False
# -- end Setup chromecast --
# Enter the infinite loop where successive images are displayed via the
# chromecast, by sending it image uri's served by our scripts webserver,
# linking the chromecast to images in our directory.
iPhoto = nStartFile
iPhotoMax = nFiles-1
while True:
try:
if player_state != cast.media_controller.status.player_state:
player_state = cast.media_controller.status.player_state
print("Player state:", player_state)
if player_state == "PLAYING":
has_played = True
if cast.socket_client.is_connected and has_played and player_state != "PLAYING":
has_played = False
cast.media_controller.play_media(args.url, "audio/mp3")
time.sleep(args.pause)
if args.do_random:
nRandom = random.random()*nFiles
iPhoto = round(nRandom)
else:
iPhoto = iPhoto + 1
if iPhoto > iPhotoMax:
iPhoto = 0
fileName = os.path.basename(filesAndPath[iPhoto])
fileUrl = urllib.parse.quote(fileName)
fileUri = 'http://'+ipAddr+':'+'8000/'+fileUrl
cast.media_controller.play_media(fileUri, MEDIA_TAG)
except KeyboardInterrupt:
break
# Shut down discovery
browser.stop_discovery()
I am trying to save audio and image from android camera to my computer in the local network using IP webcam and Matlab.
The android application allows me to access different resources using featuring URL addresses:
live streaming video: 192.168.0.105:8080/videofeed
live streaming audio in wav: format 192.168.0.105:8080/audio.wav
take one picture frame: 192.168.0.105:8080/shot.jpg
I have succeed to save images to matlab using this function (it also displays images as video in real time):
function save_screen
url = 'http://192.168.0.105:8080/shot.jpg';
ss = imread(url);
FileNum = 1;
fh = image(ss);
while(1)
pause(1)
ss = imread(url);
set(fh,'CData',ss);
drawnow;
fname = ['Image' num2str(FileNum) '.jpg'];
imwrite(ss, fname, 'JPG');
disp(['image saved ' fname]);
FileNum = FileNum + 1;
end
Now, same as with images, I am trying to save audio from URL stream in sequences of 30 seconds e.g. audio1, audio2, etc; in order to analyze it further in matlab. I have tried this with no success:
url = 'http://192.168.0.105:8080/audio.wav';
ss = wavread(url);
FileNum2 = 1;
fh = wavread(ss);
while(1)
pause(1)
ss = wavread(url);
wavwrite(ss,fname);
disp(['Sacuvava se audio ' fname]);
FileNum2 = FileNum2 + 1;
end
So to conclude, the main problem is to save 30 seconds audio sequences from URL. Any help highly appreciated