Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 815
  • Last Modified:

onMetaData, loading external movie clips

When I use this code in AS 3.0, it loads my mov just fine.

var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
myVideo.attachNetStream(ns);

var listener :Object = new Object();
listener.onMetaData = function (md:Object):void{};
ns.client = listener;

ns.play("Sample.mov");

When I use this code for AS 2.0,  I have to change void to capitalized.  Then when I run it, I get sound but no video.  Does anybody know why this is?  Do I have to add something for this to work with AS2.0 (I'm using CS3 in both cases.
0
walker6o9
Asked:
walker6o9
  • 17
  • 11
1 Solution
 
DreammonkeyCommented:
straight from the book :

The following example creates a new NetStream connection. Add a new Video symbol by opening the Library panel and selecting New Video from the Library options menu. Give the symbol the instance name my_video. Dynamically load the FLV video at runtime. Use the attachAudio() method to attach the audio from the FLV file to a movie clip on the Stage. Then you can control the audio in the movie clip by using the Sound class and two buttons called volUp_btn and volDown_btn.

var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
my_video.attachVideo(my_ns);
my_ns.play("yourVideo.flv");
this.createEmptyMovieClip("flv_mc", this.getNextHighestDepth());
flv_mc.attachAudio(my_ns);
var audio_sound:Sound = new Sound(flv_mc);

// Add volume buttons.
volUp_btn.onRelease = function() {
    if (audio_sound.getVolume()<100) {
    audio_sound.setVolume(audio_sound.getVolume()+10);
    updateVolume();
    }
};
volDown_btn.onRelease = function() {
    if (audio_sound.getVolume()>0) {
    audio_sound.setVolume(audio_sound.getVolume()-10);
    updateVolume();
    }
};

// Updates the volume.
this.createTextField("volume_txt", this.getNextHighestDepth(), 0, 0, 100, 22);
updateVolume();
function updateVolume() {
    volume_txt.text = "Volume: "+audio_sound.getVolume();
}

0
 
walker6o9Author Commented:
I want to do this for an mov though, not an flv
0
 
walker6o9Author Commented:
Nevermind, this worked for an mov.  You rule my world.
0
Easily Design & Build Your Next Website

Squarespace’s all-in-one platform gives you everything you need to express yourself creatively online, whether it is with a domain, website, or online store. Get started with your free trial today, and when ready, take 10% off your first purchase with offer code 'EXPERTS'.

 
walker6o9Author Commented:
I need to attach the video player dynamically during runtime (and attach a lot of them).  When I tried to use the attachMovieClip, i get sound but no audio.
var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
my_video = attachMovie("my_video", "my_video", 1)
my_video.attachVideo(my_ns);
my_ns.play("1.mov");
this.createEmptyMovieClip("flv_mc", this.getNextHighestDepth());
flv_mc.attachAudio(my_ns);
var audio_sound:Sound = new Sound(flv_mc);
 
 
// Add volume buttons.
volUp_btn.onRelease = function() {
    if (audio_sound.getVolume()<100) {
    audio_sound.setVolume(audio_sound.getVolume()+10);
    updateVolume();
    }
};
volDown_btn.onRelease = function() {
    if (audio_sound.getVolume()>0) {
    audio_sound.setVolume(audio_sound.getVolume()-10);
    updateVolume();
    }
};
 
// Updates the volume.
this.createTextField("volume_txt", this.getNextHighestDepth(), 0, 0, 100, 22);
updateVolume();
function updateVolume() {
    volume_txt.text = "Volume: "+audio_sound.getVolume();
}

Open in new window

0
 
DreammonkeyCommented:
my first guess is that you have to attach the audio to my_video instead of to flv_mc .
would like to check this out, working on it...
0
 
DreammonkeyCommented:
Ok, you van't just attachVideo() to any mc

create a movieClip (ctrl = F8)
name it my_video
select it in the Library,
right click, select Linkage, slect export for actionscript
double click my_video in the Library
right click on the Library panel, select New Video,name it video (video selected)
drag the newly created video into the my_video mc
give it an instance name of video

use code below
var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
my_video = attachMovie("my_video", "my_video", 1)
//my_video._x = my_video._y = 50;
my_video.video.attachVideo(my_ns);
my_ns.play("1.mov");
this.createEmptyMovieClip("flv_mc", this.getNextHighestDepth());
flv_mc.attachAudio(my_ns);
var audio_sound:Sound = new Sound(flv_mc);

Open in new window

0
 
walker6o9Author Commented:
Awesome.  I can only get this to work for one .mov file though.  I'm trying to do this for multiple mov files.  I had this code for flv files, and it worked fine, but when I modded it for mov's to correspond to the way you have your code, it only does it for the first .mov

loaderListener.onLoadError = function(eventDispatcher:MovieClip, errorCode):Void {
       father = eventDispatcher._parent
          eventDispatcher = father.attachMovie("FLVPlayer", "eventDispatcher", 6500)
      eventDispatcher.contentPath = "1.flv"
}

New code.

var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);

loaderListener.onLoadError = function(eventDispatcher:MovieClip, errorCode):Void {
       father = eventDispatcher._parent
         my_video = father.attachMovie("my_video", "my_video", 7500)

my_video.video.attachVideo(my_ns);
my_ns.play("1.mov");
}

The code is supposed to replace any missing jpg's in the image loader with 1.mov.  It replaced them all when I used the code for 1.flv, but for some reason the .mov code only replaces the first missing jpg, the rest of the spaces remain blank.
            
0
 
walker6o9Author Commented:
Oops, I mean it replaces the last missing jpg.
0
 
walker6o9Author Commented:
If I use the code below, the same basic thing happens.  It only pulls up one .mov file, at the last position.



var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
for(i=0;i<3;i++){
      
my_video = attachMovie("my_video", "my_video", i)
my_video._x = my_video._y = 300*i;
my_video.video.attachVideo(my_ns);
my_ns.play("1.mov");
}

The same is true of this code:


for(i=0;i<3;i++){
      var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
my_video = attachMovie("my_video", "my_video", i)
my_video._x = my_video._y = 300*i;
my_video.video.attachVideo(my_ns);
my_ns.play("1.mov");
}
0
 
DreammonkeyCommented:
just a qucik thought ,
does this help?
for(i=0;i<3;i++){
      var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
my_video = attachMovie("my_video", "my_video"+i, i)//get different instance names !
my_video._x = my_video._y = 300*i;
my_video.video.attachVideo(my_ns);
my_ns.play("1.mov");
}

Open in new window

0
 
walker6o9Author Commented:
That code plays audio but no video.
0
 
walker6o9Author Commented:
I tried this and it worked.  If I can do the same basic thing, except using arrays and for loops instead of manually adding 1, 2, 3, etc., then I think I can get it to work.  Of course, I have no idea how to do that.
var my_nc1:NetConnection = new NetConnection();
my_nc1.connect(null);
var my_ns1:NetStream = new NetStream(my_nc1);
my_video1 = attachMovie("my_video", "my_video"+1, 1)//get different instance names !
my_video1._x = my_video1._y = 100*1;
my_video1.video.attachVideo(my_ns1);
my_ns1.play("1.mov");
 
var my_nc2:NetConnection = new NetConnection();
my_nc2.connect(null);
var my_ns2:NetStream = new NetStream(my_nc2);
my_video2 = attachMovie("my_video", "my_video"+2, 2)//get different instance names !
my_video2._x = my_video2._y = 100*2;
my_video2.video.attachVideo(my_ns2);
my_ns2.play("1.mov");

Open in new window

0
 
DreammonkeyCommented:
The so:ution appears to be :
you create an actionlayer in the my_video MC and at this code :

var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
video.attachVideo(my_ns);
my_ns.play("1.mov");
this.createEmptyMovieClip("flv_mc", this.getNextHighestDepth());
flv_mc.attachAudio(my_ns);
var audio_sound:Sound = new Sound(flv_mc);

In the main time line actions panel you put :

var nov:Number = 4;//Number of Movies
for(i=0;i<=nov-1;i++){
      my_video = attachMovie("my_video", "my_video"+i, i)
      my_video._x = my_video._y = 50 * i;
}

Every instance of my_video will then load the same "mov.1" is that what you want?
0
 
walker6o9Author Commented:
First, I don't know what an action layer is.

Second, it will be a different movie clip each time.

Third, this will actually need to go in on onLoadError function.  What happens is, this part of the program is going through and loading in jpgs.  If there is no jpg, then it loads in an mov with the same path, just ending with .mov instead of .jpg.

Do you know if this could work inside an onLoadError function, where each time it is called, it loads a different .mov?

0
 
DreammonkeyCommented:
Hey Walker,

an actions layer, is a new layer you create in the time line, in this case you double click on the "my_video" movieclip, that we created earlier, in the Library .
The new layer automatically gets a name like "layer 33 or "layer 2" or "layer whatever". To keep things clear it's best you rename it to "actions" and then lock the layer. When you lock a layer you can no longer add images, movieclips or buttons to it, only Actionscript. This is a good way of keeping all your actionscript at the same place. This what I was refering to when I told you to :

"create an actionlayer in the my_video MC and at this code : "

var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
video.attachVideo(my_ns);
my_ns.play("1.mov");
this.createEmptyMovieClip("flv_mc", this.getNextHighestDepth());
flv_mc.attachAudio(my_ns);
var audio_sound:Sound = new Sound(flv_mc);

Secondly, if you want it to load a different movie each time, we can do this, I'll try to write someting and get back to you asap.

then, we are getting to the core of things, I'm sur this code can be implemented in the onLoadError() function, but I might have to look into your code then... could you provide me with that?

SO ... if you undertand my above post with this info, does it work for you? If not, where does it fail?

Regards,
D
0
 
DreammonkeyCommented:
Sorry man, my above post, is not clear, I'll restate what I said about the actions layer  :

an actions layer, is a new layer you create in the time line, in this case you double click on the "my_video" movieclip, that we created earlier, in the Library .
//bit missing here

Then hit the "insert layer" button on the "time line panel"(window->timeline) , this creates a new layer.
//
The new layer automatically gets a name like "layer 33 or "layer 2" or "layer whatever". To keep things clear it's best you rename it to "actions" and then lock the layer. When you lock a layer you can no longer add images, movieclips or buttons to it, only Actionscript. This is a good way of keeping all your actionscript at the same place. This what I was refering to when I told you to :
0
 
DreammonkeyCommented:
Question :
how do you read in the .jpg files?

this is essential, please provide me some of your code...

D
0
 
walker6o9Author Commented:
This creates a series of lines of images, with the height and width of each line pulled from an XML file, as well as the number of images per line.  

If there is an error, and an image does not load, it runs the onLoadError, and pulls in a .mov file from the same name.

For example, if gallery/SARA CAHOONE/lineOne/3.jpg is missing, there will be a file named gallery/SARA CAHOONE/lineOne/3.mov which will be loaded instead.  As I said before the code listed below will only replace the LAST missing jpg with an .mov.
if( _parent._parent.linkArray[_parent._parent.SelectedLink] == "intro")
{
	folderPath = "gallery/"+ _parent._parent.linkArray[_parent._parent.SelectedLink]
}else{
	folderPath = "gallery/"+ _parent._parent.linkArray[_parent._parent.SelectedLink] +"/"+ projectName
	if(projectName == undefined)
	{
		projectName = _parent._parent.clickedName.text
		folderPath = "gallery/"+ _parent._parent.linkArray[_parent._parent.SelectedLink] +"/"+ projectName
	}
}
 
 
xml = folderPath+ "/imagesGallery.xml"
var loader:MovieClipLoader = new MovieClipLoader();
 
loadInfo(xml)
var whichGallery:Array = new Array("lineOne","lineTwo", "lineThree", "lineFour", "lineFive", "lineSix", "lineSeven", "lineEight", "lineNine", "lineTen", "lineEleven", "lineTwelve", "lineThirteen", "lineFourteen", "lineFifteen");
var firstPath:String = String
var tracker:Number = new Number
var imagesGallery:Array = new Array();
var imageHeight:Array = new Array()
var imageWidth:Array = new Array()
var numImages:Array = new Array()
var column:Number = 0 
var row:Number = new Number
 
function loadInfo(which) {
	var xmlParser = new XML();
	xmlParser.load(which);
	xmlParser.ignoreWhite = true;
	xmlParser.onLoad = function(success) {
		if (success) {
			var rootNode = xmlParser.firstChild;
			var contentNode = rootNode;
			numGalleries = rootNode.childNodes[0].childNodes[1].childNodes.length
			for(i=0;i<numGalleries;i++){
			imageHeight[i] = rootNode.childNodes[0].childNodes[1].childNodes[i].childNodes[0].childNodes[0].nodeValue
			imageWidth[i] = rootNode.childNodes[0].childNodes[1].childNodes[i].childNodes[1].childNodes[0].nodeValue
			numImages[i] = rootNode.childNodes[0].childNodes[1].childNodes[i].childNodes[2].childNodes[0].nodeValue
			}
			loadImages()
		}
	}
}
 
var loader:MovieClipLoader = new MovieClipLoader();
var loaderListener:Object = new Object();
var currentThumbnail:MovieClip;
loader.addListener(loaderListener);
 
var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
 
loaderListener.onLoadError = function(eventDispatcher:MovieClip, errorCode):Void {
       father = eventDispatcher._parent
	   my_video = father.attachMovie("my_video", "my_video", 7500)
	   my_video.video.attachVideo(my_ns);
	   my_ns.play("1.mov");
}
 
function loadImages(){
for (k=0; k<numGalleries;k++) {
        var currentGallery:MovieClip = this.createEmptyMovieClip("currentGallery"+k, k);
        imagesGallery.push(currentGallery);
}
 
for(l=0; l<imagesGallery.length; l++) {
        var currentGallery:MovieClip = imagesGallery[l];
		
        currentGallery._y = column
		maskY.push(currentGallery._y)
		
		var nextColumn:Number = int(imageHeight[l]) + int(marginY)
		column += nextColumn
		
}
 
var myThumbnails:Array = new Array();
 
for(l=0;l<imagesGallery.length;l++) {
	row = 0
        for (var i:Number=0; i < numImages[l]; i++) {  
		
		
                currentThumbnail = imagesGallery[l].createEmptyMovieClip("currentThumbnail" + i,10+i);
        myThumbnails.push(currentThumbnail);
			currentRow = int(imageWidth[l]) + int(marginX)
			
                currentThumbnail._x = row;
				
				row += currentRow
				holder = currentThumbnail.createEmptyMovieClip("holder",1)
				tracker = i +1
				firstPath = folderPath+"/"+whichGallery[l]+"/"+tracker
				path = firstPath+".jpg"
				
                loader.loadClip(path, holder);
      
				currentThumbnail.myWidth = imageWidth[l]
				currentThumbnail.myHeight = imageHeight[l]
				currentThumbnail.onEnterFrame = function()
				{
					
					if(this._width>0)
					{
						this._width = this.myWidth
						this._height = this.myHeight
						
					}
					
				}
        }
}
 
}

Open in new window

0
 
DreammonkeyCommented:
could you provide the XML as well?
0
 
walker6o9Author Commented:
The part about MarginX and MarginY and popUpInfo and the stuff at the bottom can be ignored, they are used for other purposes.
<?xml version="1.0" encoding="utf-8"?><societyCo>
<section id="intro">
<info>
<marginX>4</marginX>
<marginY>4</marginY>
</info>
<info>
<gallery1>
<Height>120</Height>
<Width>111</Width>
<numberOfImages>7</numberOfImages>
<maskWidth>400</maskWidth>
<moviePopUp>2</moviePopUp>
</gallery1>
<gallery2>
<Height>100</Height>
<Width>200</Width>
<numberOfImages>10</numberOfImages>
<maskWidth>200</maskWidth>
</gallery2>
<gallery3>
<Height>100</Height>
<Width>200</Width>
<numberOfImages>2</numberOfImages>
<maskWidth>200</maskWidth>
</gallery3>
<gallery4>
<Height>120</Height>
<Width>30</Width>
<numberOfImages>7</numberOfImages>
<maskWidth>200</maskWidth>
</gallery4>
<gallery5>
<Height>100</Height>
<Width>200</Width>
<numberOfImages>10</numberOfImages>
<maskWidth>200</maskWidth>
</gallery5>
<gallery6>
<Height>100</Height>
<Width>200</Width>
<numberOfImages>10</numberOfImages>
<maskWidth>200</maskWidth>
</gallery6>
</info>
<info>
<fullScreenImage>
<popUpGalleryNum>0</popUpGalleryNum>
<popUpImageNum>2</popUpImageNum>
</fullScreenImage>
<fullScreenImage>
<popUpGalleryNum>2</popUpGalleryNum>
<popUpImageNum>1</popUpImageNum>
</fullScreenImage>
</info>
<info>
<type>MUSIC VIDEO</type>
<title><![CDATA[COUCH SONG<br>SARA CAHOONE]]></title>
<client><![CDATA[RYAN MCMACKIN<br>SARA CAHOONE]]></client>
<services><![CDATA[EDITOR<br>NARRATIVE DEVELOPMENT]]></services>
</info>
</section>
</societyCo>

Open in new window

0
 
walker6o9Author Commented:
I tried your answer to the first part of my question and it worked.  I'm trying to mod it so it works for part 2 and 3.
0
 
walker6o9Author Commented:
SUCCESS!!!  On all three counts.
0
 
DreammonkeyCommented:
I'm working on your code,
... not there yet actually, but I'm no quiter...
if you have something post it, I'm curious...
0
 
walker6o9Author Commented:
Do you know the syntax for stop, pause, and position/runtime of the video?  Or know where/how I can find a skin for this, as well as tutorials for building one of my own?
0
 
walker6o9Author Commented:
This worked perfectly.

Note: my_video code.

var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
video.attachVideo(my_ns);
my_ns.play(path);
this.createEmptyMovieClip("flv_mc", this.getNextHighestDepth());
flv_mc.attachAudio(my_ns);
var audio_sound:Sound = new Sound(flv_mc);
audio_sound.setVolume(0);

trace(path)
if( _parent._parent.linkArray[_parent._parent.SelectedLink] == "intro")
{
	folderPath = "gallery/"+ _parent._parent.linkArray[_parent._parent.SelectedLink]
}else{
	folderPath = "gallery/"+ _parent._parent.linkArray[_parent._parent.SelectedLink] +"/"+ projectName
	if(projectName == undefined)
	{
		projectName = _parent._parent.clickedName.text
		folderPath = "gallery/"+ _parent._parent.linkArray[_parent._parent.SelectedLink] +"/"+ projectName
	}
}
 
 
xml = folderPath+ "/imagesGallery.xml"
var loader:MovieClipLoader = new MovieClipLoader();
 
loadInfo(xml)
var whichGallery:Array = new Array("lineOne","lineTwo", "lineThree", "lineFour", "lineFive", "lineSix", "lineSeven", "lineEight", "lineNine", "lineTen", "lineEleven", "lineTwelve", "lineThirteen", "lineFourteen", "lineFifteen");
var firstPath:String = String
var tracker:Number = new Number
var imagesGallery:Array = new Array();
var imageHeight:Array = new Array()
var imageWidth:Array = new Array()
var numImages:Array = new Array()
var column:Number = 0 
var row:Number = new Number
 
function loadInfo(which) {
	var xmlParser = new XML();
	xmlParser.load(which);
	xmlParser.ignoreWhite = true;
	xmlParser.onLoad = function(success) {
		if (success) {
			var rootNode = xmlParser.firstChild;
			var contentNode = rootNode;
			numGalleries = rootNode.childNodes[0].childNodes[1].childNodes.length
			for(i=0;i<numGalleries;i++){
			imageHeight[i] = rootNode.childNodes[0].childNodes[1].childNodes[i].childNodes[0].childNodes[0].nodeValue
			imageWidth[i] = rootNode.childNodes[0].childNodes[1].childNodes[i].childNodes[1].childNodes[0].nodeValue
			numImages[i] = rootNode.childNodes[0].childNodes[1].childNodes[i].childNodes[2].childNodes[0].nodeValue
			}
			loadImages()
		}
	}
}
 
var loader:MovieClipLoader = new MovieClipLoader();
var loaderListener:Object = new Object();
var currentThumbnail:MovieClip;
loader.addListener(loaderListener);
 
 
 
loaderListener.onLoadError = function(eventDispatcher:MovieClip, errorCode):Void {
       father = eventDispatcher._parent
	   var gallery:Number = 0
		var thumb:Number = 0
		gallery = targetPath(father).split(".")[3].split("currentGallery")[1];
		thumb = targetPath(father).split(".")[4].split("currentThumbnail")[1];
		var thumbNumb:Number = int(thumb) + 1
	   my_video = father.attachMovie("my_video", "my_video", 7500 + gallery*50 + thumb)
	  my_video.path = folderPath +"/"+whichGallery[gallery]+"/"+thumbNumb+".mov" 
}
 
function loadImages(){
for (k=0; k<numGalleries;k++) {
        var currentGallery:MovieClip = this.createEmptyMovieClip("currentGallery"+k, k);
        imagesGallery.push(currentGallery);
}
 
for(l=0; l<imagesGallery.length; l++) {
        var currentGallery:MovieClip = imagesGallery[l];
		
        currentGallery._y = column
		maskY.push(currentGallery._y)
		
		var nextColumn:Number = int(imageHeight[l]) + int(marginY)
		column += nextColumn
		
}
 
var myThumbnails:Array = new Array();
 
for(l=0;l<imagesGallery.length;l++) {
	row = 0
        for (var i:Number=0; i < numImages[l]; i++) {  
		
		
                currentThumbnail = imagesGallery[l].createEmptyMovieClip("currentThumbnail" + i,10+i);
        myThumbnails.push(currentThumbnail);
			currentRow = int(imageWidth[l]) + int(marginX)
			
                currentThumbnail._x = row;
				
				row += currentRow
				holder = currentThumbnail.createEmptyMovieClip("holder",1)
				tracker = i +1
				firstPath = folderPath+"/"+whichGallery[l]+"/"+tracker
				path = firstPath+".jpg"
				
                loader.loadClip(path, holder);
      
				currentThumbnail.myWidth = imageWidth[l]
				currentThumbnail.myHeight = imageHeight[l]
				currentThumbnail.onEnterFrame = function()
				{
					
					if(this._width>0)
					{
						this._width = this.myWidth
						this._height = this.myHeight
						
					}
					
				}
        }
}
 
}

Open in new window

0
 
DreammonkeyCommented:
Man, I must have earned a million points by now...

go to the my_video MC, remove the video mc

add an FLVPlayBack component

give it an instance name of ... "video" or what else?

change the code in the notorious "actions layer" into :
var my_nc:NetConnection = new NetConnection();
my_nc.connect(null);
var my_ns:NetStream = new NetStream(my_nc);
video.play(path);
this.createEmptyMovieClip("flv_mc", this.getNextHighestDepth());
flv_mc.attachAudio(my_ns);
var audio_sound:Sound = new Sound(flv_mc);

Open in new window

0
 
walker6o9Author Commented:
I need an if statement or something that tells me when the movieClip is done loading.  Do you know what that looks like?

P.S. I also put this in a related question so you can get extra points.
0
 
walker6o9Author Commented:
Is there a way to build a pre-loader for this?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Easily Design & Build Your Next Website

Squarespace’s all-in-one platform gives you everything you need to express yourself creatively online, whether it is with a domain, website, or online store. Get started with your free trial today, and when ready, take 10% off your first purchase with offer code 'EXPERTS'.

  • 17
  • 11
Tackle projects and never again get stuck behind a technical roadblock.
Join Now