AVURLAsset obteniendo tamaño de video

Esto es bastante frustrante. Estoy tratando de obtener el tamaño de un AVURLasset, pero trate de evitar naturalSize como me dice Xcode, esto está en desuso en iOS5.

Pero: ¿Cuál es el reemplazo?

No puedo encontrar ninguna pista sobre cómo obtener las dimensiones del video sin usar «tamaño natural»...

preguntado el 03 de mayo de 12 a las 15:05

7 Respuestas

Resolución en Swift 3:

func resolutionSizeForLocalVideo(url:NSURL) -> CGSize? {
    guard let track = AVAsset(URL: url).tracksWithMediaType(AVMediaTypeVideo).first else { return nil }
    let size = CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform)
    return CGSize(width: fabs(size.width), height: fabs(size.height))
}

Para Swift 4:

func resolutionSizeForLocalVideo(url:NSURL) -> CGSize? {
    guard let track = AVAsset(url: url as URL).tracks(withMediaType: AVMediaType.video).first else { return nil }
    let size = track.naturalSize.applying(track.preferredTransform)
    return CGSize(width: fabs(size.width), height: fabs(size.height))
}

Soluciones sin preferredTransform ¡No devuelva valores correctos para algunos videos en los dispositivos más recientes!

contestado el 16 de mayo de 18 a las 08:05

Acabo de comprobar la documentación en línea, y el naturalSize El método está en desuso para el objeto AVAsset. Sin embargo, siempre debe haber un AVAssetTrack que se refiera al AVAsset, y el AVAssetTrack tiene un naturalSize método al que puede llamar.

tamaño natural

Las dimensiones naturales de los datos multimedia a los que hace referencia la pista. (solo lectura)

@property(no atómico, solo lectura) CGSize tamaño natural

Disponibilidad

Disponible en iOS 4.0 y posteriores. Declarado en AVAssetTrack.h

Vía: Referencia de AVAssetTrack para iOS

contestado el 03 de mayo de 12 a las 17:05

nautralSize está en desuso en iOS 5 - Raptor

acabo de consultar los documentos en el enlace de la respuesta, y no está en desuso, está disponible tanto en ObjC como en Swift: C4-Travis

hay 2 naturalSize en las documentaciones. AVURLAsset.naturalSize está en desuso, pero [[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize] no es - Raptor

Mi respuesta especifica el AVAssetTrack enfoque, que no está en desuso y que es lo que Dave especifica en su segunda línea de código a continuación ... Parece que simplemente no agregué la línea de código a mi respuesta. - C4-Travis

Entonces, todos cambian a hacer básicamente lo mismo que hizo el método obsoleto. Estupendo. - sudo

La advertencia de desaprobación en la documentación oficial sugiere, "Utilice el naturalSize y preferredTransform, según corresponda, de las pistas de vídeo del activo en su lugar (consulte también tracksWithMediaType:). "

Cambié mi código de:

CGSize size = [movieAsset naturalSize];

a

CGSize size = [[[movieAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];

Es menos bonito y menos seguro ahora, pero no se romperá cuando dejen caer ese método.

Respondido 20 ago 13, 01:08

La advertencia de desaprobación dice:

Use the naturalSize and preferredTransform, as appropriate, 
of the asset’s video tracks instead (see also tracksWithMediaType:).

Así que necesitamos un AVAssetTrack, y queremos su tamaño natural y transformación preferida. Se puede acceder a esto con lo siguiente:

AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
CGSize dimensions = CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform);

activo es obviamente tu AVA activo.

Respondido el 07 de enero de 15 a las 19:01

Hmmm, aplicar la transformación como sugieres da como resultado un ancho negativo para mí :( - Goz

@Goz Simplemente normalice los componentes de dimensión usando fabsf(). - Jack

Esta es una extensión bastante simple para AVAsset in Swift 4 para obtener el tamaño del video, si está disponible:

extension AVAsset {
    var screenSize: CGSize? {
        if let track = tracks(withMediaType: .video).first {
            let size = __CGSizeApplyAffineTransform(track.naturalSize, track.preferredTransform)
            return CGSize(width: fabs(size.width), height: fabs(size.height))
        } 
        return nil
    }
}

Respondido el 21 de enero de 18 a las 02:01

Gracias, aunque la aplicación está escrita en Objective-C (todavía tengo que reescribirla). Veré si puedo adaptar tu extensión... - tipo suizo

hola tengo el mismo problema encontraste solucion?? porque en mi caso, usar el tamaño natural + preferirTransform devuelve un valor obsoleto :( gracias - sarra.srairi

Para derivar la dimensión de un AVAsset, debe calcular la unión de todas las rectas de la pista visual (después de aplicar su transformación preferida correspondiente):

CGRect unionRect = CGRectZero;
for (AVAssetTrack *track in [asset tracksWithMediaCharacteristic:AVMediaCharacteristicVisual]) {
    CGRect trackRect = CGRectApplyAffineTransform(CGRectMake(0.f,
                                                             0.f,
                                                             track.naturalSize.width,
                                                             track.naturalSize.height),
                                                  track.preferredTransform);
    unionRect = CGRectUnion(unionRect, trackRect);
}
CGSize naturalSize = unionRect.size;

Métodos que se basan en CGSizeApplyAffineTransform fallan cuando su activo contiene pistas con transformación afín no trivial (p. ej., rotaciones de 45 grados) o si su activo contiene pistas con diferentes orígenes (p. ej., dos pistas que se reproducen una al lado de la otra con el origen de la segunda pista aumentado por el ancho del primera pista).

Ver: MediaPlayerPrivateAVFoundationCF::sizeChanged()at https://opensource.apple.com/source/WebCore/WebCore-7536.30.2/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp

respondido 10 mar '17, 01:03

Aunque David, para AVAsset que contiene una pista de video, la respuesta de @Avt funciona correctamente. ¿Correcto? - Roi Mulía

@RoiMulia: Creo que es poco común que los activos tengan una sola pista de video con un desplazamiento distinto de cero. Por eso, es poco probable que veas el error al usar ese código. Además, he visto jugadores que ignoran el desplazamiento cuando el activo solo contiene una pista. Si le interesa manejar estos casos extremos, le recomiendo que experimente usted mismo para verificar el comportamiento real. - David H

Para Swift 5

  let assetSize =  asset.tracks(withMediaType: .video)[0].naturalSize

Respondido 17 ago 20, 13:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.