Giter Site home page Giter Site logo

Comments (32)

oseiasmribeiro avatar oseiasmribeiro commented on July 4, 2024 4

_audioPlayer.icyMetadataStream.listen(
(icyEvent) { ... }
); works well for android, but how to get the audio title on iOS?

from just_audio.

Jei avatar Jei commented on July 4, 2024 2

Hey @pblinux !
Yes, it's definitely the way to do it. I was working on a solution yesterday using onTracksChanged, however, I was only checking the first TrackGroup of the trackGroups array. It worked for my specific case, but your idea of iterating over the entire trackGroups array is probably safer. I'll commit the changes and work on the PR.

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024 2

I feel I can increase my personal priority for this issue now. I would still at least like to get the visualizer feature published first and make the one-isolate branch of audio_service stable, but following that I'd like to get the iOS implementation of this feature implemented for completeness.

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024 2

I will have a go at it tonight.

Note to self:

https://developer.apple.com/documentation/avfoundation/avplayeritemmetadataoutput?language=objc

from just_audio.

blackraven96 avatar blackraven96 commented on July 4, 2024 2

Thx for your work :)

You can test with this streams :
http://str0.creacast.com/classique1
http://icecast.skyrock.net/s/natio_aac_64k?tvr_name=tunein16&tvr_section1=32aac
http://kissfm.ice.infomaniak.ch/kissfm-128.mp3

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024 2

I've implemented iOS/macOS support in the latest commit. Note that all of the streams I tested only provided "title" metadata, and because I reverse engineered the keys from the metadata in those test URLs above, the title is the only metadata it is coded for. I will try to support other metadata keys if anyone provides a URL that exhibits them.

Let me know how it goes. One thing I wanted to be careful about was introducing a retain cycle. I don't think I've done that, but if you notice any memory leak (e.g. memory retained after player item or player itself is disposed), please let me know.

from just_audio.

Jei avatar Jei commented on July 4, 2024 1

I've opened an issue in the ExoPlayer repository to ask for clarifications on how to retrieve IcyHeaders: google/ExoPlayer#7266

from just_audio.

neutronstein avatar neutronstein commented on July 4, 2024 1

I was able to get current playing title on iOS. It worked well in simulator.

from just_audio.

APSchuurman avatar APSchuurman commented on July 4, 2024 1

Just ran into this issue and updating to latest version solved it.
Tested it on a real iOS device.

Thanks a lot for your great work.

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

Thanks, Jei. I'd certainly be happy to accept a PR once you finish it as I think this could be useful to others. If you're only adding some more fields and a stream, I don't think that should break anything.

from just_audio.

pblinux avatar pblinux commented on July 4, 2024

Hello @Jei @ryanheise.

About the IcyInfo that's not retrieving, I think or it's a ExoPlayer issue or it's the DataSource, I'm not sure.

This are the things I tried so far:

  • Creating a DefaultHttpDataSourceFactory and adding a property Icy-MetaData", "1". Nothing changes.
DefaultHttpDataSourceFactory httpDataSource = new 
    DefaultHttpDataSourceFactory(Util.getUserAgent(context, "just_audio"), null);
httpDataSource.getDefaultRequestProperties().set("Icy-MetaData", "1");
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(context, httpDataSource);
  • Adding a audioAttribute to the player, nothing changes.
player.setAudioAttributes(new AudioAttributes.Builder().setContentType(C.CONTENT_TYPE_MUSIC).setUsage(C.USAGE_MEDIA).build());
  • Using an external library: I found this metadata retriever and it works, this retrieves the icy-headers correctly:
    https://github.com/vsmaks/audiostream-metadata-retriever
    • The problem here, I think, that this makes an additional request for the data.
    • Also, it's outdated so I had to add tools:replace="android:label" to my project AndroidManifest

from just_audio.

Jei avatar Jei commented on July 4, 2024

Thank you for the pointers @pblinux.
I've tried to add the ExoPlayer's OkHttp extension to use OkHttpDataSourceFactory instead of DefaultHttpDataSourceFactory, but it doesn't make any difference. However by logging the HTTP calls I was able to confirm that the Icy headers are being received correctly:

D/OkHttp  (22180): --> GET http://stream2.mpegradio.com:8070/tormented.mp3
D/OkHttp  (22180): Icy-MetaData: 1
D/OkHttp  (22180): User-Agent: just_audio/1.0.0 (Linux;Android 9) ExoPlayerLib/2.11.1
D/OkHttp  (22180): Accept-Encoding: identity
D/OkHttp  (22180): --> END GET
D/OkHttp  (22180): <-- 200 OK http://stream2.mpegradio.com:8070/tormented.mp3 (605ms)
D/OkHttp  (22180): icy-notice1: <BR>This stream requires <a href="http://www.winamp.com">Winamp</a><BR>
D/OkHttp  (22180): icy-notice2: SHOUTcast DNAS/posix(linux x64) v2.5.5.733<BR>
D/OkHttp  (22180): Accept-Ranges: none
D/OkHttp  (22180): Access-Control-Allow-Origin: *
D/OkHttp  (22180): Cache-Control: no-cache,no-store,must-revalidate,max-age=0
D/OkHttp  (22180): Connection: close
D/OkHttp  (22180): icy-name: -=- tormented radio -=- streaming since 1998
D/OkHttp  (22180): icy-genre: Industrial
D/OkHttp  (22180): icy-br: 128
D/OkHttp  (22180): icy-sr: 44100
D/OkHttp  (22180): icy-url: http://www.tormentedradio.com
D/OkHttp  (22180): icy-pub: 1
D/OkHttp  (22180): content-type: audio/mpeg
D/OkHttp  (22180): icy-metaint: 16384
D/OkHttp  (22180): X-Clacks-Overhead: GNU Terry Pratchett

Note that I didn't have to set the Icy-MetaData header manually, it's part of the request sent by ExoPlayer.
I'll keep looking.

from just_audio.

pblinux avatar pblinux commented on July 4, 2024

Hello @Jei

I just tested what they said, it works.

onTracksChanged it's the way that exoplayer expose those headers.

@Override
	public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
		for (int i = 0; i < trackGroups.length; i++) {
			TrackGroup trackGroup = trackGroups.get(i);
			for (int j = 0; j < trackGroup.length; j++) {
				Metadata trackMetadata = trackGroup.getFormat(j).metadata;
				if (trackMetadata != null) {
					Log.d("just-audio:", trackMetadata.toString());
				}
			}
		}
	}

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

Thank, @Jei ! I've merged your PR and added a stub for iOS/macOS.

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

It is not implemented on iOS yet. I've reopened this issue, and I'll note below a useful reference example for how I might be able to implement it:

https://stackoverflow.com/questions/27955125/timed-metadata-with-avplayer

from just_audio.

oseiasmribeiro avatar oseiasmribeiro commented on July 4, 2024

@Jei Can you add this option also for iOS too? I'm not that expert yet. LOL I really need this in my project!

from just_audio.

Jei avatar Jei commented on July 4, 2024

Hey @oseiasmribeiro! Unfortunately, I don't own any Apple device at the moment, so I don't think I'll be able to write and test the iOS version of these changes. It's also the reason why I released my current project only on the Play Store.

from just_audio.

oseiasmribeiro avatar oseiasmribeiro commented on July 4, 2024

@Jei Ok. Thanks!

from just_audio.

silver-cap avatar silver-cap commented on July 4, 2024

for iOS, not yet? If somebody helps, very very thanks.

from just_audio.

Okladnoj avatar Okladnoj commented on July 4, 2024

This is a very egregious question !!! And there are still no solutions (((

I spent 3 days on the Internet looking for a solution, but I did not achieve my goal.

Dear Developer please help us. Metadata is a very important part of any music file.
In the modern world without the name of the composition - no one needs you!

I will attach the results of my searches. I really hope that this will help you to improve the plugin)

1

You've @Jei seen it already. But there were updates. I started my search with this, but I was defeated

2

There are also 2 interesting codes here
1
2
I translated it all into swift

let playerItem = AVPlayerItem(url: url)
let metadataList = playerItem.asset.commonMetadata
for metaItem in metadataList {
    if let common = metaItem.commonKey {
        print("\(common)")
    }
}
let titleIndex = (avItem.asset.commonMetadata as NSArray).indexOfObject(passingTest: { obj, idx, stop in
    let metaItem = obj as? AVMutableMetadataItem
    if metaItem?.commonKey?.isEqual(toString: AVMetadataKey.commonKeyTitle) != nil {
        return true
    }
    return false
})

let item = avItem.asset.commonMetadata[titleIndex] as? AVMutableMetadataItem
let title = item?.value as? String

3

This is similar to the first link, but more expanded

4

Quite an interesting tip
Вот что у меня из этого получилось, но не сработало:

let url = URL(fileURLWithPath: st)
               let asset = AVAsset(url: url)
               let formatsKey = "playable"
               asset.loadValuesAsynchronously(forKeys: [formatsKey]) {
                   var error: NSError? = nil
                   let status = asset.statusOfValue(forKey: formatsKey, error: &error)
                   if status == .loaded {
                       for format in asset.availableMetadataFormats {
                           let metadata = asset.metadata(forFormat: format)
                           // process format-specific metadata collection
                           print("\(metadata)")
                       }
                   }
               }
               let metadataItems = asset.commonMetadata
               let metadataItem = AVMetadataItem.metadataItems(from: metadataItems, filteredByIdentifier: AVMetadataIdentifier.commonIdentifierArtwork)
               print(metadataItem);
               let playerItem = AVPlayerItem(url: url)
               let metadataList = playerItem.asset.commonMetadata
               for metaItem in metadataList {
                   if let common = metaItem.commonKey {
                       print("\(common)")
                   }
               }

5

I accidentally found code like this. I thought it would help, but I'm a noob in swift ((( And of course, nothing came of it ...

from just_audio.

Okladnoj avatar Okladnoj commented on July 4, 2024

@Jei
Please help us. tell me at least what needs to be changed at:
Project \ ios \ Runner \ AppDelegate.swift

some kind of temporary solution.

I hope my searches, in the previous post, will help you

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

I agree that this would be a very worthwhile feature to have on iOS, although please do keep in mind this is a collaborative effort. I will have my own priorities for which feature I will implement next (e.g. a visualiser and equaliser, or gapless looping), but other contributors may also have their own priorities, so if you can't wait for me alone to implement every single feature, it will just take the right contributor who is sufficiently motivated and wants this feature urgently enough to become a project contributor, and help out the project in the same way that @Jei graciously contributed the Android implementation.

Contributions are definitely welcome, even from those who are completely new to iOS and the Objective C programming language (several people have contributed Objective C code without having any prior experience with Objective C, so that is possible.)

from just_audio.

mohammadne avatar mohammadne commented on July 4, 2024

Hi, I don't have a deep knowledge about audio metadata or icy-metadata and difference between two but I am wonder to know that
is it possible to have audio thumbnail image (cover art) and description fields in metadata?

from just_audio.

blackraven96 avatar blackraven96 commented on July 4, 2024

Still no one for added this functionnalty on IOS ? :)

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

@blackraven96 I am currently working on the visualiser feature, followed by nnbd (maybe this will come first), then maybe web assets/files, alongside bugs that crop up.

I have posted a link above on how this could be implemented, but it will just take someone sufficiently motivated to submit a pull request and jump the queue (otherwise if I implement it, it will happen after completing other items which are a higher priority for me personally).

Would you be interested in trying your hand at some Objective C code?

from just_audio.

Okladnoj avatar Okladnoj commented on July 4, 2024

We are waiting for your decision ...

from just_audio.

neutronstein avatar neutronstein commented on July 4, 2024

Also waiting for this feature. Hope it gets implemented in the next few days :)
Thanks for your amaizing work

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

I'll hopefully make time for it this week. In the meantime, please post below some URLs of audio you would like me to use as this cases.

from just_audio.

neutronstein avatar neutronstein commented on July 4, 2024

Fingers crossed. Currently building a radio app for iOS and metadata are missing.
https://www.radioking.com/play/note-radio

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

I'm testing https://www.radioking.com/play/note-radio and am picking up the title.

Does anyone have more URLs to test, with more metadata?

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

Any feedback/reports so far?

from just_audio.

ryanheise avatar ryanheise commented on July 4, 2024

Just to update, I've added support for the URL metadata on iOS. It's implemented in the fix/ios_livestream branch.

Will anyone be able to test this on their streams to confirm whether it works for you before I publish?

from just_audio.

Related Issues (20)

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.